1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.css;
16
17 import org.htmlunit.BrowserVersion;
18 import org.htmlunit.SimpleWebTestCase;
19 import org.htmlunit.css.ComputedCssStyleDeclaration;
20 import org.htmlunit.css.CssStyleSheet;
21 import org.htmlunit.cssparser.parser.CSSErrorHandler;
22 import org.htmlunit.cssparser.parser.CSSException;
23 import org.htmlunit.cssparser.parser.CSSOMParser;
24 import org.htmlunit.cssparser.parser.CSSParseException;
25 import org.htmlunit.cssparser.parser.javacc.CSS3Parser;
26 import org.htmlunit.cssparser.parser.selector.Selector;
27 import org.htmlunit.cssparser.parser.selector.SelectorList;
28 import org.htmlunit.cssparser.parser.selector.SelectorListImpl;
29 import org.htmlunit.html.DomElement;
30 import org.htmlunit.html.HtmlElement;
31 import org.htmlunit.html.HtmlForm;
32 import org.htmlunit.html.HtmlInput;
33 import org.htmlunit.html.HtmlPage;
34 import org.htmlunit.html.HtmlStyle;
35 import org.htmlunit.javascript.host.html.HTMLStyleElement;
36 import org.htmlunit.junit.BrowserRunner;
37 import org.htmlunit.junit.annotation.Alerts;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.w3c.dom.NodeList;
41
42
43
44
45
46
47
48
49 @RunWith(BrowserRunner.class)
50 public class CSSStyleSheet2Test extends SimpleWebTestCase {
51
52
53
54
55 @Test
56 public void selects_miscSelectors() throws Exception {
57 final String html = DOCTYPE_HTML
58 + "<html><head><title>test</title>\n"
59 + "</head><body><style></style>\n"
60 + "<form name='f1' action='foo' class='yui-log'>\n"
61 + "<div><div><input name='i1' id='m1'></div></div>\n"
62 + "<input name='i2' class='yui-log'>\n"
63 + "<button name='b1' class='yui-log'>\n"
64 + "<button name='b2'>\n"
65 + "</form>\n"
66 + "</body></html>";
67
68 final HtmlPage page = loadPage(html);
69 final HtmlElement body = page.getBody();
70 final HtmlForm form = page.getFormByName("f1");
71 final HtmlInput input1 = (HtmlInput) page.getElementsByName("i1").get(0);
72 final HtmlInput input2 = (HtmlInput) page.getElementsByName("i2").get(0);
73 final DomElement button1 = page.getElementsByName("b1").get(0);
74 final DomElement button2 = page.getElementsByName("b2").get(0);
75 final BrowserVersion browserVersion = getBrowserVersion();
76
77 final HtmlStyle node = (HtmlStyle) page.getElementsByTagName("style").item(0);
78 final HTMLStyleElement host = (HTMLStyleElement) node.getScriptableObject();
79 final CSSStyleSheet sheet = host.getSheet();
80
81 Selector selector = parseSelector(sheet, "*.yui-log input");
82
83 assertFalse(CssStyleSheet.selects(browserVersion, selector, body, null, false, true));
84 assertFalse(CssStyleSheet.selects(browserVersion, selector, form, null, false, true));
85 assertTrue(CssStyleSheet.selects(browserVersion, selector, input1, null, false, true));
86 assertTrue(CssStyleSheet.selects(browserVersion, selector, input2, null, false, true));
87 assertFalse(CssStyleSheet.selects(browserVersion, selector, button1, null, false, true));
88 assertFalse(CssStyleSheet.selects(browserVersion, selector, button2, null, false, true));
89
90 selector = parseSelector(sheet, "#m1");
91 assertTrue(CssStyleSheet.selects(browserVersion, selector, input1, null, false, true));
92 assertFalse(CssStyleSheet.selects(browserVersion, selector, input2, null, false, true));
93 }
94
95 private static Selector parseSelector(final CSSStyleSheet sheet, final String rule) throws Exception {
96 return parseSelectors(rule).get(0);
97 }
98
99 private static SelectorList parseSelectors(final String source) throws Exception {
100 SelectorList selectors;
101 final CSSErrorHandler errorHandler = new CSSErrorHandler() {
102
103 @Override
104 public void warning(final CSSParseException exception) throws CSSException {
105 throw exception;
106 }
107
108 @Override
109 public void fatalError(final CSSParseException exception) throws CSSException {
110 throw exception;
111 }
112
113 @Override
114 public void error(final CSSParseException exception) throws CSSException {
115 throw exception;
116 }
117 };
118 final CSSOMParser parser = new CSSOMParser(new CSS3Parser());
119 parser.setErrorHandler(errorHandler);
120 selectors = parser.parseSelectors(source);
121
122 if (null == selectors) {
123 selectors = new SelectorListImpl();
124 }
125 return selectors;
126 }
127
128
129
130
131 @Test
132 public void selects_anyNodeSelector() throws Exception {
133 testSelects("*", true, true, true);
134 }
135
136
137
138
139 @Test
140 public void selects_childSelector() throws Exception {
141 testSelects("body > div", false, true, false);
142 }
143
144
145
146
147 @Test
148 public void selects_descendantSelector() throws Exception {
149 testSelects("body span", false, false, true);
150 }
151
152
153
154
155 @Test
156 public void selects_elementSelector() throws Exception {
157 testSelects("div", false, true, false);
158 }
159
160
161
162
163 @Test
164 public void selects_directAdjacentSelector() throws Exception {
165 testSelects("span + span", false, false, true);
166 }
167
168
169
170
171 @Test
172 public void selects_conditionalSelector_idCondition() throws Exception {
173 testSelects("span#s", false, false, true);
174 testSelects("#s", false, false, true);
175 testSelects("span[id=s]", false, false, true);
176 }
177
178
179
180
181 @Test
182 public void selectsIdConditionWithSpecialChars() throws Exception {
183 final String html = DOCTYPE_HTML
184 + "<html><body><style></style>\n"
185 + "<div id='d:e'></div>\n"
186 + "<div id='d-e'></div>\n"
187 + "</body></html>";
188 final HtmlPage page = loadPage(html);
189 final BrowserVersion browserVersion = getBrowserVersion();
190
191 Selector selector = parseSelectors("#d\\:e").get(0);
192 assertTrue(CssStyleSheet.selects(browserVersion, selector, page.getHtmlElementById("d:e"), null, false, true));
193
194 selector = parseSelectors("#d-e").get(0);
195 assertTrue(CssStyleSheet.selects(browserVersion, selector, page.getHtmlElementById("d-e"), null, false, true));
196 }
197
198
199
200
201 @Test
202 public void selects_conditionalSelector_classCondition() throws Exception {
203 testSelects("div.bar", false, true, false);
204 testSelects(".bar", false, true, false);
205 testSelects("div[class~=bar]", false, true, false);
206 }
207
208
209
210
211 @Test
212 public void selects_pseudoClass_root() throws Exception {
213 testSelects(":root", false, false, false);
214 }
215
216
217
218
219 @Test
220 public void selects_pseudoClass_lang() throws Exception {
221 testSelects(":lang(en)", false, true, true);
222 testSelects(":lang(de)", false, false, false);
223 }
224
225
226
227
228 @Test
229 public void selects_pseudoClass_negation() throws Exception {
230 testSelects(":not(div)", true, false, true);
231 }
232
233 private void testSelects(final String css, final boolean selectBody, final boolean selectDivD,
234 final boolean selectSpanS) throws Exception {
235 final String html = DOCTYPE_HTML
236 + "<html>\n"
237 + " <body id='b'>\n"
238 + " <style></style>\n"
239 + " <div id='d' class='foo bar' lang='en-GB'>\n"
240 + " <span>x</span>\n"
241 + " <span id='s'>a</span>b\n"
242 + " </div>\n"
243 + " </body>\n"
244 + "</html>";
245 final HtmlPage page = loadPage(html);
246 final BrowserVersion browserVersion = getBrowserVersion();
247
248 final Selector selector = parseSelectors(css).get(0);
249 assertEquals(selectBody,
250 CssStyleSheet.selects(browserVersion, selector, page.getHtmlElementById("b"), null, false, true));
251 assertEquals(selectDivD,
252 CssStyleSheet.selects(browserVersion, selector, page.getHtmlElementById("d"), null, false, true));
253 assertEquals(selectSpanS,
254 CssStyleSheet.selects(browserVersion, selector, page.getHtmlElementById("s"), null, false, true));
255 }
256
257
258
259
260
261 @Test
262 @Alerts("ComputedCssStyleDeclaration for 'HtmlBody[<body>]'")
263 public void brokenExternalCSS() throws Exception {
264 final String html = "<html><head>\n"
265 + "<link rel='stylesheet' type='text/css' href='" + URL_SECOND + "'/></head></html>";
266
267 getMockWebConnection().setResponse(URL_SECOND, "body { font-weight: 900\\9; }");
268 final HtmlPage htmlPage = loadPage(html);
269
270 final NodeList list = htmlPage.getElementsByTagName("body");
271 final HtmlElement element = (HtmlElement) list.item(0);
272 final ComputedCssStyleDeclaration style = htmlPage.getEnclosingWindow().getComputedStyle(element, null);
273 assertEquals(getExpectedAlerts()[0], style.toString());
274 }
275 }