1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test for CSS parser reporting parsing errors with expected precision</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<style id="testbench"></style>
<script>
SpecialPowers.wrap(window).docShell.cssErrorReportingEnabled = true;
// Tests that apply to all types of style sheets
var tests = [
{
css: "@unknown {}",
error: "Unrecognized at-rule or error parsing at-rule ‘@unknown’.",
}, {
css: "x { color: invalid; }",
error: "Expected color but found ‘invalid’. Error in parsing value for ‘color’. Declaration dropped.",
cssSelectors: "x",
}, {
css: "x { filter: alpha(foo); }",
error: "Expected ‘none’, URL, or filter function but found ‘alpha(’. Error in parsing value for ‘filter’. Declaration dropped.",
cssSelectors: "x",
}, {
css: "x { color: red; abc; }",
error: "Unknown property ‘abc;’. Declaration dropped.",
cssSelectors: "x",
}, {
css: "x { filter: 5; }",
error: "Expected ‘none’, URL, or filter function but found ‘5’. Error in parsing value for ‘filter’. Declaration dropped.",
cssSelectors: "x",
}, {
css: "::unknown {}",
error: "Unknown pseudo-class or pseudo-element ‘unknown’. Ruleset ignored due to bad selector.",
}, {
css: ":unknown {}",
error: "Unknown pseudo-class or pseudo-element ‘unknown’. Ruleset ignored due to bad selector.",
}, {
css: "::5 {}",
error: "Expected identifier for pseudo-class or pseudo-element but found ‘5’. Ruleset ignored due to bad selector.",
}, {
css: ": {}",
error: "Expected identifier for pseudo-class or pseudo-element but found ‘ ’. Ruleset ignored due to bad selector.",
}, {
css: "x[a.]{}",
error: "Unexpected token in attribute selector: ‘.’. Ruleset ignored due to bad selector.",
}, {
css: "x[*a]{}",
error: "Expected ‘|’ but found ‘a’. Ruleset ignored due to bad selector.",
}, {
css: "x[a=5]{}",
error: "Expected identifier or string for value in attribute selector but found ‘5’. Ruleset ignored due to bad selector.",
}, {
css: "x[$] {}",
error: "Expected attribute name or namespace but found ‘$’. Ruleset ignored due to bad selector.",
}, {
css: "a[|5] {}",
error: "Expected identifier for attribute name but found ‘5’. Ruleset ignored due to bad selector.",
}, {
css: "a[x|] {}",
error: "Unknown namespace prefix ‘x’. Ruleset ignored due to bad selector.",
}, {
css: "x| {}",
error: "Unknown namespace prefix ‘x’. Ruleset ignored due to bad selector.",
}, {
css: "a> {}",
error: "Dangling combinator. Ruleset ignored due to bad selector.",
}, {
css: "~ {}",
error: "Selector expected. Ruleset ignored due to bad selector.",
}, {
css: "| {}",
error: "Expected element name or ‘*’ but found ‘ ’. Ruleset ignored due to bad selector.",
}, {
css: ". {}",
error: "Expected identifier for class selector but found ‘ ’. Ruleset ignored due to bad selector.",
}, {
css: ":not() {}",
error: "Selector expected. Ruleset ignored due to bad selector.",
}, {
css: "* { -webkit-text-size-adjust: 100% }",
error: "Error in parsing value for ‘-webkit-text-size-adjust’. Declaration dropped.",
cssSelectors: "*",
}, {
css: "@media (totally-unknown-feature) {}",
error: "Expected media feature name but found ‘totally-unknown-feature’.",
}, {
css: "@media \"foo\" {}",
error: "Unexpected token ‘\"foo\"’ in media list.",
}, {
css: "@media (min-width) {}",
error: "Media features with min- or max- must have a value.",
}, {
css: "@media (min-width >= 3px) {}",
error: "Unexpected operator in media list.",
}, {
css: "@media (device-height: three) {}",
error: "Found invalid value for media feature.",
}, {
css: "@media (min-width: foo) {}",
error: "Found invalid value for media feature.",
}, {
css: "@media (min-resolution: 2) {}",
error: "Found invalid value for media feature.",
}, {
css: "@media (min-monochrome: 1.1) {}",
error: "Found invalid value for media feature.",
}, {
css: "@media (min-aspect-ratio: 1 invalid) {}",
error: "Unexpected token ‘invalid’ in media list.",
}, {
css: "@media (min-aspect-ratio: 1 / invalid) {}",
error: "Found invalid value for media feature.",
}, {
css: "@media (orientation: invalid-orientation-value) {}",
error: "Found invalid value for media feature.",
}, {
css: "a, .b, #c { unknown: invalid; }",
error: "Unknown property ‘unknown’. Declaration dropped.",
cssSelectors: "a, .b, #c"
},
{
css: ":host:hover { color: red; }",
error: ":host selector in ‘:host:hover’ is not featureless and will never match. Maybe you intended to use :host()?"
},
{
css: "@position-try --foo { width: 10px !important; }",
error: "Property cannot be declared as !important in this context. Declaration dropped."
},
{
css: '@property --my-property { initial-value: green; inherits: true; }',
error: "@property syntax descriptor is missing."
},
{
css: '@property --my-property { syntax: "<color>"; initial-value: green; }',
error: "@property inherits descriptor is missing."
},
{
css: '@property --my-property { syntax: "<color>"; initial-value: green; inherits: maybe; }',
error: "@property inherits descriptor ‘inherits: maybe;’ does not match specified syntax."
},
{
css: 'foo { :host(:not[bar]) & { color: red } }',
// This is not the most ideal error, but it's better than nothing.
error: "Unknown property ‘:host(:not[bar]) & {’. Declaration dropped.",
cssSelectors: "foo",
},
];
// Tests that apply only to constructed style sheets
var constructedSheetTests = [
{
css: '@import url("sheet.css");',
error: "@import rules are not yet valid in constructed stylesheets."
}
];
function assertMessages(messages, action) {
return new Promise(resolve => {
SimpleTest.expectConsoleMessages(action, messages, resolve);
});
}
async function runTests() {
for (let {css, cssSelectors = "", error} of tests) {
let messages = [ { cssSelectors, errorMessage: error } ];
await assertMessages(messages, () => { testbench.innerHTML = css });
await assertMessages(messages, () => { new CSSStyleSheet().replaceSync(css) });
await assertMessages(messages, async () => { await new CSSStyleSheet().replace(css) });
}
for (let {css, cssSelectors = "", error} of constructedSheetTests) {
let messages = [ { cssSelectors, errorMessage: error } ];
await assertMessages(messages, () => { new CSSStyleSheet().replaceSync(css) });
await assertMessages(messages, async () => { await new CSSStyleSheet().replace(css) });
}
}
add_task(runTests);
</script>
|