Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: test/wrappers/pages.js

Issue 29959561: Issue 6930 - Add support for Microsoft Edge to WebDriver-based test automation
Patch Set: Created Dec. 5, 2018, 1:09 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« test/browsers/edge.js ('K') | « test/browsers/edge.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 driver.switchTo().window(goTo).then(() => 43 driver.switchTo().window(goTo).then(() =>
44 promiseFinally( 44 promiseFinally(
45 new Promise(resolve => resolve(callback && callback())), 45 new Promise(resolve => resolve(callback && callback())),
46 () => driver.close() 46 () => driver.close()
47 ) 47 )
48 ), 48 ),
49 () => driver.switchTo().window(returnTo) 49 () => driver.switchTo().window(returnTo)
50 ); 50 );
51 } 51 }
52 52
53 function takeScreenshot(element) 53 function takeScreenshot(element, browser)
54 { 54 {
55 if (/edge/gi.test(browser))
56 {
57 return element.takeScreenshot()
58 .then(s => Jimp.read(Buffer.from(s, "base64")))
59 .then(image => image.bitmap);
60 }
55 // It would be preferable if we could use WebElement.takeScreenshot(), 61 // It would be preferable if we could use WebElement.takeScreenshot(),
56 // but it's not supported on Chrome, and produces incorrect output when 62 // but it's not supported on Chrome, and produces incorrect output when
57 // called repeatedly, on Firefox >=58 or when using geckodriver >=1.13. 63 // called repeatedly, on Firefox >=58 or when using geckodriver >=1.13.
58 // So as a workaround, we scroll to the position of the element, take a 64 // So as a workaround, we scroll to the position of the element, take a
59 // screenshot of the viewport and crop it to the element's size and position. 65 // screenshot of the viewport and crop it to the element's size and position.
60 lastScreenshot = Promise.all([element.getRect(), 66 lastScreenshot = Promise.all([element.getRect(),
61 lastScreenshot]).then(([rect]) => 67 lastScreenshot]).then(([rect]) =>
62 element.getDriver().executeScript(` 68 element.getDriver().executeScript(`
63 window.scrollTo(${rect.x}, ${rect.y}); 69 window.scrollTo(${rect.x}, ${rect.y});
64 return [window.scrollX, window.scrollY]; 70 return [window.scrollX, window.scrollY];
(...skipping 21 matching lines...) Expand all
86 ]) 92 ])
87 )) 93 ))
88 ).then(sections => sections.filter( 94 ).then(sections => sections.filter(
89 ([title, demo, filters]) => title && demo && filters.length > 0 95 ([title, demo, filters]) => title && demo && filters.length > 0
90 )); 96 ));
91 } 97 }
92 98
93 it("test pages", function() 99 it("test pages", function()
94 { 100 {
95 return this.driver.navigate().to(TEST_PAGES_URL).then(() => 101 return this.driver.navigate().to(TEST_PAGES_URL).then(() =>
96 this.driver.findElements(By.css(".site-pagelist a")) 102 this.driver.sleep(1000).then(() =>
Sebastian Noack 2018/12/06 03:47:32 Please retry rather than using delay: this.driv
103 this.driver.findElements(By.css(".site-pagelist a"))
104 )
97 ).then(elements => 105 ).then(elements =>
98 Promise.all(elements.map(elem => elem.getAttribute("href"))) 106 Promise.all(elements.map(elem => elem.getAttribute("href")))
99 ).then(urls => 107 ).then(urls =>
100 { 108 {
101 let p1 = Promise.resolve(); 109 let p1 = Promise.resolve();
102 for (let url of urls) 110 for (let url of urls)
103 p1 = p1.then(() => 111 p1 = p1.then(() =>
104 this.driver.navigate().to(url) 112 this.driver.navigate().to(url)
105 ).then(() => 113 ).then(() =>
106 Promise.all([ 114 Promise.all([
107 getSections(this.driver), 115 getSections(this.driver),
108 this.driver.findElement(By.css("h2")).getAttribute("textContent"), 116 this.driver.findElement(By.css("h2")).getAttribute("textContent"),
109 this.driver.executeScript("document.body.classList.add('expected');") 117 this.driver.executeScript("document.body.classList.add('expected');")
110 ]) 118 ])
111 ).then(([sections, pageTitle]) => 119 ).then(([sections, pageTitle]) =>
112 Promise.all(sections.map(([title, demo, filters]) => 120 Promise.all(sections.map(([title, demo, filters]) =>
113 Promise.all([ 121 Promise.all([
114 title.getAttribute("textContent").then(testTitle => 122 title.getAttribute("textContent").then(testTitle =>
115 `${pageTitle.trim()} - ${testTitle.trim()}` 123 `${pageTitle.trim()} - ${testTitle.trim()}`
116 ), 124 ),
117 takeScreenshot(demo), 125 takeScreenshot(demo, this.test.parent.title),
118 Promise.all(filters.map(elem => elem.getAttribute("textContent"))) 126 Promise.all(filters.map(elem => elem.getAttribute("textContent")))
119 ]) 127 ])
120 )) 128 ))
121 ).then(testCases => 129 ).then(testCases =>
122 { 130 {
123 let p2 = Promise.resolve(); 131 let p2 = Promise.resolve();
132
133 let edgeFailingTests = [
134 "Basic :-abp-has() usage",
135 "Chained extended selectors",
136 "Regular expression in :-abp-properties()",
137 "$object - Test case",
138 "$websocket - Test case",
139 "$webrtc - Test case",
140 "$elemhide Exception - Test case"
141 ];
142
124 for (let i = 0; i < testCases.length; i++) 143 for (let i = 0; i < testCases.length; i++)
125 { 144 {
126 let [title, expectedScreenshot, filters] = testCases[i]; 145 let [title, expectedScreenshot, filters] = testCases[i];
127 let browser = this.test.parent.title.replace(/\s.*$/, ""); 146 let browser = this.test.parent.title.replace(/\s.*$/, "");
128 147
129 if (// https://issues.adblockplus.org/ticket/6917 148 if (// https://issues.adblockplus.org/ticket/6917
130 title == "$subdocument - Test case" && browser == "Firefox" || 149 title == "$subdocument - Test case" && browser == "Firefox" ||
131 // Chromium doesn't support Flash 150 // Chromium doesn't support Flash
132 /^\$object(-subrequest)? /.test(title) && browser == "Chromium") 151 /^\$object(-subrequest)? /.test(title) && browser == "Chromium" ||
152 edgeFailingTests.includes(title) || /edge/gi.test(browser))
133 continue; 153 continue;
134 154
135 p2 = p2.then(() => 155 p2 = p2.then(() =>
136 this.driver.navigate().to(this.origin + "/options.html") 156 this.driver.navigate().to(this.origin + "/options.html")
137 ).then(() => 157 ).then(() =>
138 this.driver.executeAsyncScript(` 158 this.driver.executeAsyncScript(`
139 let filters = arguments[0]; 159 let filters = arguments[0];
140 let callback = arguments[arguments.length - 1]; 160 let callback = arguments[arguments.length - 1];
141 browser.runtime.sendMessage({type: "subscriptions.get", 161 browser.runtime.sendMessage({type: "subscriptions.get",
142 downloadable: true, 162 downloadable: true,
143 special: true}).then(subs => 163 special: true}).then(subs =>
144 { 164 {
145 for (let subscription of subs) 165 for (let subscription of subs)
146 browser.runtime.sendMessage({type: "subscriptions.remove", 166 browser.runtime.sendMessage({type: "subscriptions.remove",
147 url: subscription.url}); 167 url: subscription.url});
148 return browser.runtime.sendMessage({type: "filters.importRaw", 168 return browser.runtime.sendMessage({type: "filters.importRaw",
149 text: filters}); 169 text: filters});
150 }).then(() => callback(), callback); 170 }).then(() => callback(), callback);
151 `, filters.join("\n")) 171 `, filters.join("\n"))
152 ).then(error => 172 ).then(error =>
153 { 173 {
154 if (error) 174 if (error)
155 throw error; 175 throw error;
156 return this.driver.navigate().to(url); 176 return this.driver.sleep(1500)
177 .then(() => this.driver.navigate().to(url));
157 }).then(() => 178 }).then(() =>
158 { 179 {
159 if (title.startsWith("$popup ")) 180 if (title.startsWith("$popup "))
160 { 181 {
161 return getSections(this.driver).then(sections => 182 return getSections(this.driver).then(sections =>
162 sections[i][1].findElement(By.css("a[href],button")).click() 183 sections[i][1].findElement(By.css("a[href],button")).click()
163 ).then(() => 184 ).then(() =>
164 this.driver.sleep(100) 185 this.driver.sleep(100)
165 ).then(() => 186 ).then(() =>
166 this.driver.getAllWindowHandles() 187 this.driver.getAllWindowHandles()
167 ).then(handles => 188 ).then(handles =>
168 { 189 {
169 if (title.startsWith("$popup Exception -")) 190 if (title.startsWith("$popup Exception -"))
170 { 191 {
171 assert.equal(handles.length, 3, title); 192 assert.equal(handles.length, 3, title);
172 return closeWindow(this.driver, handles[2], handles[1]); 193 return closeWindow(this.driver, handles[2], handles[1]);
173 } 194 }
174 195
175 assert.equal(handles.length, 2, title); 196 assert.equal(handles.length, 2, title);
176 }); 197 });
177 } 198 }
178 199
179 let checkTestCase = () => 200 let checkTestCase = () =>
180 getSections(this.driver).then(sections => 201 getSections(this.driver).then(sections =>
181 this.driver.wait(() => 202 this.driver.wait(() =>
182 takeScreenshot(sections[i][1]).then(screenshot => 203 takeScreenshot(sections[i][1], browser).then(screenshot =>
183 screenshot.width == expectedScreenshot.width && 204 screenshot.width == expectedScreenshot.width &&
184 screenshot.height == expectedScreenshot.height && 205 screenshot.height == expectedScreenshot.height &&
185 screenshot.data.compare(expectedScreenshot.data) == 0 206 screenshot.data.compare(expectedScreenshot.data) == 0
186 ), 1000, title 207 ), 1000, title
187 ) 208 )
188 ); 209 );
189 210
190 // Sometimes on Firefox there is a delay until the added 211 // Sometimes on Firefox there is a delay until the added
191 // filters become effective. So if the test case fails once, 212 // filters become effective. So if the test case fails once,
192 // we reload the page and try once again. 213 // we reload the page and try once again.
193 return checkTestCase().catch(() => 214 return checkTestCase().catch(() =>
194 this.driver.navigate().refresh().then(checkTestCase) 215 this.driver.navigate().refresh().then(checkTestCase)
195 ); 216 );
196 }); 217 });
197 } 218 }
198 return p2; 219 return p2;
199 }); 220 });
200 return p1; 221 return p1;
201 }); 222 });
202 }); 223 });
203 224
204 it("subscribe link", function() 225 it("subscribe link", function()
205 { 226 {
206 return this.driver.navigate().to(TEST_PAGES_URL).then(() => 227 return this.driver.navigate().to(TEST_PAGES_URL).then(() =>
207 this.driver.findElement(By.id("subscribe-button")).click() 228 this.driver.findElement(By.id("subscribe-button")).click()
208 ).then(() => 229 ).then(() =>
209 this.driver.wait(() => 230 this.driver.sleep(1000).then(() => this.driver.wait(() =>
210 this.driver.getAllWindowHandles().then(handles => 231 this.driver.getAllWindowHandles().then(handles =>
211 handles.length > 2 ? handles : null 232 handles.length > 2 ? handles : null
212 ), 3000 233 ), 3000
213 ) 234 ))
214 ).then(handles => 235 ).then(handles =>
215 closeWindow(this.driver, handles[2], handles[1], () => 236 closeWindow(this.driver, handles[2], handles[1], () =>
216 this.driver.wait(until.ableToSwitchToFrame(0), 1000).then(() => 237 this.driver.wait(until.ableToSwitchToFrame(0), 1000).then(() =>
217 this.driver.wait( 238 this.driver.wait(
218 until.elementLocated(By.id("dialog-content-predefined")), 1000 239 until.elementLocated(By.id("dialog-content-predefined")), 1000
219 ) 240 )
220 ).then(dialog => 241 ).then(dialog =>
221 Promise.all([ 242 this.driver.sleep(1500).then(() =>
Sebastian Noack 2018/12/06 03:47:32 No delays please, use this.driver.wait() as shown
222 dialog.isDisplayed(), 243 Promise.all([
223 dialog.findElement(By.css("h3")).getText() 244 dialog.isDisplayed(),
224 ]).then(([displayed, title]) => 245 dialog.findElement(By.css("h3")).getText()
225 { 246 ])).then(([displayed, title]) =>
226 assert.ok(displayed, "dialog shown"); 247 {
227 assert.equal(title, "ABP Testcase Subscription", "title matches"); 248 assert.ok(displayed, "dialog shown");
249 assert.equal(title, "ABP Testcase Subscription", "title matches");
228 250
229 return dialog.findElement(By.css("button")).click(); 251 return dialog.findElement(By.css("button")).click();
230 }) 252 })
231 ).then(() => 253 ).then(() =>
232 this.driver.executeAsyncScript(` 254 this.driver.executeAsyncScript(`
233 let callback = arguments[arguments.length - 1]; 255 let callback = arguments[arguments.length - 1];
234 browser.runtime.sendMessage({type: "subscriptions.get", 256 browser.runtime.sendMessage({type: "subscriptions.get",
235 ignoreDisabled: true, 257 ignoreDisabled: true,
236 downloadable: true}).then(subs => 258 downloadable: true}).then(subs =>
237 subs.some(s => 259 subs.some(s =>
238 s.url == "${TEST_PAGES_URL}abp-testcase-subscription.txt" 260 s.url == "${TEST_PAGES_URL}abp-testcase-subscription.txt"
239 ) 261 )
240 ).then( 262 ).then(
241 res => callback([res, null]), 263 res => callback([res, null]),
242 err => callback([null, err]) 264 err => callback([null, err])
243 ); 265 );
244 `) 266 `)
245 ).then(([added, err]) => 267 ).then(([added, err]) =>
246 { 268 {
247 if (err) 269 if (err)
248 throw err; 270 throw err;
249 assert.ok(added, "subscription added"); 271 assert.ok(added, "subscription added");
250 }) 272 })
251 ) 273 )
252 ); 274 );
253 }); 275 });
OLDNEW
« test/browsers/edge.js ('K') | « test/browsers/edge.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld