Best JavaScript code snippet using sinon
navigation.spec.js
Source:navigation.spec.js
...25 setupTestPageAndContextHooks();26 describe('Page.goto', function () {27 it('should work', async () => {28 const { page, server } = getTestState();29 await page.goto(server.EMPTY_PAGE);30 expect(page.url()).toBe(server.EMPTY_PAGE);31 });32 it('should work with anchor navigation', async () => {33 const { page, server } = getTestState();34 await page.goto(server.EMPTY_PAGE);35 expect(page.url()).toBe(server.EMPTY_PAGE);36 await page.goto(server.EMPTY_PAGE + '#foo');37 expect(page.url()).toBe(server.EMPTY_PAGE + '#foo');38 await page.goto(server.EMPTY_PAGE + '#bar');39 expect(page.url()).toBe(server.EMPTY_PAGE + '#bar');40 });41 it('should work with redirects', async () => {42 const { page, server } = getTestState();43 server.setRedirect('/redirect/1.html', '/redirect/2.html');44 server.setRedirect('/redirect/2.html', '/empty.html');45 await page.goto(server.PREFIX + '/redirect/1.html');46 expect(page.url()).toBe(server.EMPTY_PAGE);47 });48 it('should navigate to about:blank', async () => {49 const { page } = getTestState();50 const response = await page.goto('about:blank');51 expect(response).toBe(null);52 });53 it('should return response when page changes its URL after load', async () => {54 const { page, server } = getTestState();55 const response = await page.goto(server.PREFIX + '/historyapi.html');56 expect(response.status()).toBe(200);57 });58 it('should work with subframes return 204', async () => {59 const { page, server } = getTestState();60 server.setRoute('/frames/frame.html', (req, res) => {61 res.statusCode = 204;62 res.end();63 });64 await page.goto(server.PREFIX + '/frames/one-frame.html');65 });66 it('should fail when server returns 204', async () => {67 const { page, server, isChrome } = getTestState();68 server.setRoute('/empty.html', (req, res) => {69 res.statusCode = 204;70 res.end();71 });72 let error = null;73 await page.goto(server.EMPTY_PAGE).catch((error_) => (error = error_));74 expect(error).not.toBe(null);75 if (isChrome) expect(error.message).toContain('net::ERR_ABORTED');76 else expect(error.message).toContain('NS_BINDING_ABORTED');77 });78 it('should navigate to empty page with domcontentloaded', async () => {79 const { page, server } = getTestState();80 const response = await page.goto(server.EMPTY_PAGE, {81 waitUntil: 'domcontentloaded',82 });83 expect(response.status()).toBe(200);84 });85 it('should work when page calls history API in beforeunload', async () => {86 const { page, server } = getTestState();87 await page.goto(server.EMPTY_PAGE);88 await page.evaluate(() => {89 window.addEventListener(90 'beforeunload',91 () => history.replaceState(null, 'initial', window.location.href),92 false93 );94 });95 const response = await page.goto(server.PREFIX + '/grid.html');96 expect(response.status()).toBe(200);97 });98 it('should navigate to empty page with networkidle0', async () => {99 const { page, server } = getTestState();100 const response = await page.goto(server.EMPTY_PAGE, {101 waitUntil: 'networkidle0',102 });103 expect(response.status()).toBe(200);104 });105 it('should navigate to empty page with networkidle2', async () => {106 const { page, server } = getTestState();107 const response = await page.goto(server.EMPTY_PAGE, {108 waitUntil: 'networkidle2',109 });110 expect(response.status()).toBe(200);111 });112 it('should fail when navigating to bad url', async () => {113 const { page, isChrome } = getTestState();114 let error = null;115 await page.goto('asdfasdf').catch((error_) => (error = error_));116 if (isChrome)117 expect(error.message).toContain('Cannot navigate to invalid URL');118 else expect(error.message).toContain('Invalid url');119 });120 it('should fail when navigating to bad SSL', async () => {121 const { page, httpsServer, isChrome } = getTestState();122 // Make sure that network events do not emit 'undefined'.123 // @see https://crbug.com/750469124 page.on('request', (request) => expect(request).toBeTruthy());125 page.on('requestfinished', (request) => expect(request).toBeTruthy());126 page.on('requestfailed', (request) => expect(request).toBeTruthy());127 let error = null;128 await page129 .goto(httpsServer.EMPTY_PAGE)130 .catch((error_) => (error = error_));131 if (isChrome)132 expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');133 else expect(error.message).toContain('SSL_ERROR_UNKNOWN');134 });135 it('should fail when navigating to bad SSL after redirects', async () => {136 const { page, server, httpsServer, isChrome } = getTestState();137 server.setRedirect('/redirect/1.html', '/redirect/2.html');138 server.setRedirect('/redirect/2.html', '/empty.html');139 let error = null;140 await page141 .goto(httpsServer.PREFIX + '/redirect/1.html')142 .catch((error_) => (error = error_));143 if (isChrome)144 expect(error.message).toContain('net::ERR_CERT_AUTHORITY_INVALID');145 else expect(error.message).toContain('SSL_ERROR_UNKNOWN');146 });147 it('should throw if networkidle is passed as an option', async () => {148 const { page, server } = getTestState();149 let error = null;150 await page151 .goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' })152 .catch((error_) => (error = error_));153 expect(error.message).toContain(154 '"networkidle" option is no longer supported'155 );156 });157 it('should fail when main resources failed to load', async () => {158 const { page, isChrome } = getTestState();159 let error = null;160 await page161 .goto('http://localhost:44123/non-existing-url')162 .catch((error_) => (error = error_));163 if (isChrome)164 expect(error.message).toContain('net::ERR_CONNECTION_REFUSED');165 else expect(error.message).toContain('NS_ERROR_CONNECTION_REFUSED');166 });167 it('should fail when exceeding maximum navigation timeout', async () => {168 const { page, server, puppeteer } = getTestState();169 // Hang for request to the empty.html170 server.setRoute('/empty.html', (req, res) => {});171 let error = null;172 await page173 .goto(server.PREFIX + '/empty.html', { timeout: 1 })174 .catch((error_) => (error = error_));175 expect(error.message).toContain('Navigation timeout of 1 ms exceeded');176 expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);177 });178 it('should fail when exceeding default maximum navigation timeout', async () => {179 const { page, server, puppeteer } = getTestState();180 // Hang for request to the empty.html181 server.setRoute('/empty.html', (req, res) => {});182 let error = null;183 page.setDefaultNavigationTimeout(1);184 await page185 .goto(server.PREFIX + '/empty.html')186 .catch((error_) => (error = error_));187 expect(error.message).toContain('Navigation timeout of 1 ms exceeded');188 expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);189 });190 it('should fail when exceeding default maximum timeout', async () => {191 const { page, server, puppeteer } = getTestState();192 // Hang for request to the empty.html193 server.setRoute('/empty.html', (req, res) => {});194 let error = null;195 page.setDefaultTimeout(1);196 await page197 .goto(server.PREFIX + '/empty.html')198 .catch((error_) => (error = error_));199 expect(error.message).toContain('Navigation timeout of 1 ms exceeded');200 expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);201 });202 it('should prioritize default navigation timeout over default timeout', async () => {203 const { page, server, puppeteer } = getTestState();204 // Hang for request to the empty.html205 server.setRoute('/empty.html', (req, res) => {});206 let error = null;207 page.setDefaultTimeout(0);208 page.setDefaultNavigationTimeout(1);209 await page210 .goto(server.PREFIX + '/empty.html')211 .catch((error_) => (error = error_));212 expect(error.message).toContain('Navigation timeout of 1 ms exceeded');213 expect(error).toBeInstanceOf(puppeteer.errors.TimeoutError);214 });215 it('should disable timeout when its set to 0', async () => {216 const { page, server } = getTestState();217 let error = null;218 let loaded = false;219 page.once('load', () => (loaded = true));220 await page221 .goto(server.PREFIX + '/grid.html', { timeout: 0, waitUntil: ['load'] })222 .catch((error_) => (error = error_));223 expect(error).toBe(null);224 expect(loaded).toBe(true);225 });226 it('should work when navigating to valid url', async () => {227 const { page, server } = getTestState();228 const response = await page.goto(server.EMPTY_PAGE);229 expect(response.ok()).toBe(true);230 });231 it('should work when navigating to data url', async () => {232 const { page } = getTestState();233 const response = await page.goto('data:text/html,hello');234 expect(response.ok()).toBe(true);235 });236 it('should work when navigating to 404', async () => {237 const { page, server } = getTestState();238 const response = await page.goto(server.PREFIX + '/not-found');239 expect(response.ok()).toBe(false);240 expect(response.status()).toBe(404);241 });242 it('should return last response in redirect chain', async () => {243 const { page, server } = getTestState();244 server.setRedirect('/redirect/1.html', '/redirect/2.html');245 server.setRedirect('/redirect/2.html', '/redirect/3.html');246 server.setRedirect('/redirect/3.html', server.EMPTY_PAGE);247 const response = await page.goto(server.PREFIX + '/redirect/1.html');248 expect(response.ok()).toBe(true);249 expect(response.url()).toBe(server.EMPTY_PAGE);250 });251 it('should wait for network idle to succeed navigation', async () => {252 const { page, server } = getTestState();253 let responses = [];254 // Hold on to a bunch of requests without answering.255 server.setRoute('/fetch-request-a.js', (req, res) => responses.push(res));256 server.setRoute('/fetch-request-b.js', (req, res) => responses.push(res));257 server.setRoute('/fetch-request-c.js', (req, res) => responses.push(res));258 server.setRoute('/fetch-request-d.js', (req, res) => responses.push(res));259 const initialFetchResourcesRequested = Promise.all([260 server.waitForRequest('/fetch-request-a.js'),261 server.waitForRequest('/fetch-request-b.js'),262 server.waitForRequest('/fetch-request-c.js'),263 ]);264 const secondFetchResourceRequested = server.waitForRequest(265 '/fetch-request-d.js'266 );267 // Navigate to a page which loads immediately and then does a bunch of268 // requests via javascript's fetch method.269 const navigationPromise = page.goto(server.PREFIX + '/networkidle.html', {270 waitUntil: 'networkidle0',271 });272 // Track when the navigation gets completed.273 let navigationFinished = false;274 navigationPromise.then(() => (navigationFinished = true));275 // Wait for the page's 'load' event.276 await new Promise((fulfill) => page.once('load', fulfill));277 expect(navigationFinished).toBe(false);278 // Wait for the initial three resources to be requested.279 await initialFetchResourcesRequested;280 // Expect navigation still to be not finished.281 expect(navigationFinished).toBe(false);282 // Respond to initial requests.283 for (const response of responses) {284 response.statusCode = 404;285 response.end(`File not found`);286 }287 // Reset responses array288 responses = [];289 // Wait for the second round to be requested.290 await secondFetchResourceRequested;291 // Expect navigation still to be not finished.292 expect(navigationFinished).toBe(false);293 // Respond to requests.294 for (const response of responses) {295 response.statusCode = 404;296 response.end(`File not found`);297 }298 const response = await navigationPromise;299 // Expect navigation to succeed.300 expect(response.ok()).toBe(true);301 });302 it('should not leak listeners during navigation', async () => {303 const { page, server } = getTestState();304 let warning = null;305 const warningHandler = (w) => (warning = w);306 process.on('warning', warningHandler);307 for (let i = 0; i < 20; ++i) await page.goto(server.EMPTY_PAGE);308 process.removeListener('warning', warningHandler);309 expect(warning).toBe(null);310 });311 it('should not leak listeners during bad navigation', async () => {312 const { page } = getTestState();313 let warning = null;314 const warningHandler = (w) => (warning = w);315 process.on('warning', warningHandler);316 for (let i = 0; i < 20; ++i)317 await page.goto('asdf').catch((error) => {318 /* swallow navigation error */319 });320 process.removeListener('warning', warningHandler);321 expect(warning).toBe(null);322 });323 it('should not leak listeners during navigation of 11 pages', async () => {324 const { context, server } = getTestState();325 let warning = null;326 const warningHandler = (w) => (warning = w);327 process.on('warning', warningHandler);328 await Promise.all(329 [...Array(20)].map(async () => {330 const page = await context.newPage();331 await page.goto(server.EMPTY_PAGE);332 await page.close();333 })334 );335 process.removeListener('warning', warningHandler);336 expect(warning).toBe(null);337 });338 it('should navigate to dataURL and fire dataURL requests', async () => {339 const { page } = getTestState();340 const requests = [];341 page.on(342 'request',343 (request) => !utils.isFavicon(request) && requests.push(request)344 );345 const dataURL = 'data:text/html,<div>yo</div>';346 const response = await page.goto(dataURL);347 expect(response.status()).toBe(200);348 expect(requests.length).toBe(1);349 expect(requests[0].url()).toBe(dataURL);350 });351 it('should navigate to URL with hash and fire requests without hash', async () => {352 const { page, server } = getTestState();353 const requests = [];354 page.on(355 'request',356 (request) => !utils.isFavicon(request) && requests.push(request)357 );358 const response = await page.goto(server.EMPTY_PAGE + '#hash');359 expect(response.status()).toBe(200);360 expect(response.url()).toBe(server.EMPTY_PAGE);361 expect(requests.length).toBe(1);362 expect(requests[0].url()).toBe(server.EMPTY_PAGE);363 });364 it('should work with self requesting page', async () => {365 const { page, server } = getTestState();366 const response = await page.goto(server.PREFIX + '/self-request.html');367 expect(response.status()).toBe(200);368 expect(response.url()).toContain('self-request.html');369 });370 it('should fail when navigating and show the url at the error message', async () => {371 const { page, httpsServer } = getTestState();372 const url = httpsServer.PREFIX + '/redirect/1.html';373 let error = null;374 try {375 await page.goto(url);376 } catch (error_) {377 error = error_;378 }379 expect(error.message).toContain(url);380 });381 it('should send referer', async () => {382 const { page, server } = getTestState();383 const [request1, request2] = await Promise.all([384 server.waitForRequest('/grid.html'),385 server.waitForRequest('/digits/1.png'),386 page.goto(server.PREFIX + '/grid.html', {387 referer: 'http://google.com/',388 }),389 ]);390 expect(request1.headers['referer']).toBe('http://google.com/');391 // Make sure subresources do not inherit referer.392 expect(request2.headers['referer']).toBe(server.PREFIX + '/grid.html');393 });394 });395 describe('Page.waitForNavigation', function () {396 it('should work', async () => {397 const { page, server } = getTestState();398 await page.goto(server.EMPTY_PAGE);399 const [response] = await Promise.all([400 page.waitForNavigation(),401 page.evaluate(402 (url) => (window.location.href = url),403 server.PREFIX + '/grid.html'404 ),405 ]);406 expect(response.ok()).toBe(true);407 expect(response.url()).toContain('grid.html');408 });409 it('should work with both domcontentloaded and load', async () => {410 const { page, server } = getTestState();411 let response = null;412 server.setRoute('/one-style.css', (req, res) => (response = res));413 const navigationPromise = page.goto(server.PREFIX + '/one-style.html');414 const domContentLoadedPromise = page.waitForNavigation({415 waitUntil: 'domcontentloaded',416 });417 let bothFired = false;418 const bothFiredPromise = page419 .waitForNavigation({420 waitUntil: ['load', 'domcontentloaded'],421 })422 .then(() => (bothFired = true));423 await server.waitForRequest('/one-style.css');424 await domContentLoadedPromise;425 expect(bothFired).toBe(false);426 response.end();427 await bothFiredPromise;428 await navigationPromise;429 });430 it('should work with clicking on anchor links', async () => {431 const { page, server } = getTestState();432 await page.goto(server.EMPTY_PAGE);433 await page.setContent(`<a href='#foobar'>foobar</a>`);434 const [response] = await Promise.all([435 page.waitForNavigation(),436 page.click('a'),437 ]);438 expect(response).toBe(null);439 expect(page.url()).toBe(server.EMPTY_PAGE + '#foobar');440 });441 it('should work with history.pushState()', async () => {442 const { page, server } = getTestState();443 await page.goto(server.EMPTY_PAGE);444 await page.setContent(`445 <a onclick='javascript:pushState()'>SPA</a>446 <script>447 function pushState() { history.pushState({}, '', 'wow.html') }448 </script>449 `);450 const [response] = await Promise.all([451 page.waitForNavigation(),452 page.click('a'),453 ]);454 expect(response).toBe(null);455 expect(page.url()).toBe(server.PREFIX + '/wow.html');456 });457 it('should work with history.replaceState()', async () => {458 const { page, server } = getTestState();459 await page.goto(server.EMPTY_PAGE);460 await page.setContent(`461 <a onclick='javascript:replaceState()'>SPA</a>462 <script>463 function replaceState() { history.replaceState({}, '', '/replaced.html') }464 </script>465 `);466 const [response] = await Promise.all([467 page.waitForNavigation(),468 page.click('a'),469 ]);470 expect(response).toBe(null);471 expect(page.url()).toBe(server.PREFIX + '/replaced.html');472 });473 it('should work with DOM history.back()/history.forward()', async () => {474 const { page, server } = getTestState();475 await page.goto(server.EMPTY_PAGE);476 await page.setContent(`477 <a id=back onclick='javascript:goBack()'>back</a>478 <a id=forward onclick='javascript:goForward()'>forward</a>479 <script>480 function goBack() { history.back(); }481 function goForward() { history.forward(); }482 history.pushState({}, '', '/first.html');483 history.pushState({}, '', '/second.html');484 </script>485 `);486 expect(page.url()).toBe(server.PREFIX + '/second.html');487 const [backResponse] = await Promise.all([488 page.waitForNavigation(),489 page.click('a#back'),490 ]);491 expect(backResponse).toBe(null);492 expect(page.url()).toBe(server.PREFIX + '/first.html');493 const [forwardResponse] = await Promise.all([494 page.waitForNavigation(),495 page.click('a#forward'),496 ]);497 expect(forwardResponse).toBe(null);498 expect(page.url()).toBe(server.PREFIX + '/second.html');499 });500 it('should work when subframe issues window.stop()', async () => {501 const { page, server } = getTestState();502 server.setRoute('/frames/style.css', (req, res) => {});503 const navigationPromise = page.goto(504 server.PREFIX + '/frames/one-frame.html'505 );506 const frame = await utils.waitEvent(page, 'frameattached');507 await new Promise((fulfill) => {508 page.on('framenavigated', (f) => {509 if (f === frame) fulfill();510 });511 });512 await Promise.all([513 frame.evaluate(() => window.stop()),514 navigationPromise,515 ]);516 });517 });518 describe('Page.goBack', function () {519 it('should work', async () => {520 const { page, server } = getTestState();521 await page.goto(server.EMPTY_PAGE);522 await page.goto(server.PREFIX + '/grid.html');523 let response = await page.goBack();524 expect(response.ok()).toBe(true);525 expect(response.url()).toContain(server.EMPTY_PAGE);526 response = await page.goForward();527 expect(response.ok()).toBe(true);528 expect(response.url()).toContain('/grid.html');529 response = await page.goForward();530 expect(response).toBe(null);531 });532 it('should work with HistoryAPI', async () => {533 const { page, server } = getTestState();534 await page.goto(server.EMPTY_PAGE);535 await page.evaluate(() => {536 history.pushState({}, '', '/first.html');537 history.pushState({}, '', '/second.html');538 });539 expect(page.url()).toBe(server.PREFIX + '/second.html');540 await page.goBack();541 expect(page.url()).toBe(server.PREFIX + '/first.html');542 await page.goBack();543 expect(page.url()).toBe(server.EMPTY_PAGE);544 await page.goForward();545 expect(page.url()).toBe(server.PREFIX + '/first.html');546 });547 });548 describe('Frame.goto', function () {549 it('should navigate subframes', async () => {550 const { page, server } = getTestState();551 await page.goto(server.PREFIX + '/frames/one-frame.html');552 expect(page.frames()[0].url()).toContain('/frames/one-frame.html');553 expect(page.frames()[1].url()).toContain('/frames/frame.html');554 const response = await page.frames()[1].goto(server.EMPTY_PAGE);555 expect(response.ok()).toBe(true);556 expect(response.frame()).toBe(page.frames()[1]);557 });558 it('should reject when frame detaches', async () => {559 const { page, server } = getTestState();560 await page.goto(server.PREFIX + '/frames/one-frame.html');561 server.setRoute('/empty.html', () => {});562 const navigationPromise = page563 .frames()[1]564 .goto(server.EMPTY_PAGE)565 .catch((error_) => error_);566 await server.waitForRequest('/empty.html');567 await page.$eval('iframe', (frame) => frame.remove());568 const error = await navigationPromise;569 expect(error.message).toBe('Navigating frame was detached');570 });571 it('should return matching responses', async () => {572 const { page, server } = getTestState();573 // Disable cache: otherwise, chromium will cache similar requests.574 await page.setCacheEnabled(false);575 await page.goto(server.EMPTY_PAGE);576 // Attach three frames.577 const frames = await Promise.all([578 utils.attachFrame(page, 'frame1', server.EMPTY_PAGE),579 utils.attachFrame(page, 'frame2', server.EMPTY_PAGE),580 utils.attachFrame(page, 'frame3', server.EMPTY_PAGE),581 ]);582 // Navigate all frames to the same URL.583 const serverResponses = [];584 server.setRoute('/one-style.html', (req, res) =>585 serverResponses.push(res)586 );587 const navigations = [];588 for (let i = 0; i < 3; ++i) {589 navigations.push(frames[i].goto(server.PREFIX + '/one-style.html'));590 await server.waitForRequest('/one-style.html');591 }592 // Respond from server out-of-order.593 const serverResponseTexts = ['AAA', 'BBB', 'CCC'];594 for (const i of [1, 2, 0]) {595 serverResponses[i].end(serverResponseTexts[i]);596 const response = await navigations[i];597 expect(response.frame()).toBe(frames[i]);598 expect(await response.text()).toBe(serverResponseTexts[i]);599 }600 });601 });602 describe('Frame.waitForNavigation', function () {603 it('should work', async () => {604 const { page, server } = getTestState();605 await page.goto(server.PREFIX + '/frames/one-frame.html');606 const frame = page.frames()[1];607 const [response] = await Promise.all([608 frame.waitForNavigation(),609 frame.evaluate(610 (url) => (window.location.href = url),611 server.PREFIX + '/grid.html'612 ),613 ]);614 expect(response.ok()).toBe(true);615 expect(response.url()).toContain('grid.html');616 expect(response.frame()).toBe(frame);617 expect(page.url()).toContain('/frames/one-frame.html');618 });619 it('should fail when frame detaches', async () => {620 const { page, server } = getTestState();621 await page.goto(server.PREFIX + '/frames/one-frame.html');622 const frame = page.frames()[1];623 server.setRoute('/empty.html', () => {});624 let error = null;625 const navigationPromise = frame626 .waitForNavigation()627 .catch((error_) => (error = error_));628 await Promise.all([629 server.waitForRequest('/empty.html'),630 frame.evaluate(() => (window.location = '/empty.html')),631 ]);632 await page.$eval('iframe', (frame) => frame.remove());633 await navigationPromise;634 expect(error.message).toBe('Navigating frame was detached');635 });636 });637 describe('Page.reload', function () {638 it('should work', async () => {639 const { page, server } = getTestState();640 await page.goto(server.EMPTY_PAGE);641 await page.evaluate(() => (window._foo = 10));642 await page.reload();643 expect(await page.evaluate(() => window._foo)).toBe(undefined);644 });645 });...
navigation.js
Source:navigation.js
...20 await helper.end()21})22test.serial('Page.goto should work', async t => {23 const { page, server } = t.context24 await page.goto(server.EMPTY_PAGE)25 t.is(page.url(), server.EMPTY_PAGE)26})27test.serial('Page.goto should work with anchor navigation', async t => {28 const { page, server } = t.context29 await page.goto(server.EMPTY_PAGE)30 t.is(page.url(), server.EMPTY_PAGE)31 await page.goto(server.EMPTY_PAGE + '#foo')32 t.is(page.url(), server.EMPTY_PAGE + '#foo')33 await page.goto(server.EMPTY_PAGE + '#bar')34 t.is(page.url(), server.EMPTY_PAGE + '#bar')35})36test.serial('Page.goto should work with redirects', async t => {37 const { page, server } = t.context38 await page.goto(server.PREFIX + '/redirect/1.html')39 t.is(page.url(), server.EMPTY_PAGE)40})41test.serial('Page.goto should navigate to about:blank', async t => {42 const { page, server } = t.context43 const response = await page.goto('about:blank')44 t.falsy(response)45})46test.serial(47 'Page.goto should return response when page changes its URL after load',48 async t => {49 const { page, server } = t.context50 const response = await page.goto(server.PREFIX + '/historyapi.html')51 t.is(response.status(), 200)52 }53)54test.serial('Page.goto should work with subframes return 204', async t => {55 const { page, server } = t.context56 await page.goto(server.PREFIX + '/frames/subFrameNoContent.html')57 t.pass()58})59test.serial('Page.goto should fail when server returns 204', async t => {60 const { page, server } = t.context61 let error = null62 await page.goto(server.PREFIX + '/endlessVoid').catch(e => (error = e))63 t.truthy(error)64 t.true(error.message.includes('net::ERR_ABORTED'))65})66test.serial(67 'Page.goto should navigate to empty page with domcontentloaded',68 async t => {69 const { page, server } = t.context70 const response = await page.goto(server.EMPTY_PAGE, {71 waitUntil: 'domcontentloaded'72 })73 t.is(response.status(), 200)74 }75)76test.serial(77 'Page.goto should work when page calls history API in beforeunload',78 async t => {79 const { page, server } = t.context80 await page.goto(server.EMPTY_PAGE)81 await page.evaluate(() => {82 window.addEventListener(83 'beforeunload',84 () => history.replaceState(null, 'initial', window.location.href),85 false86 )87 })88 const response = await page.goto(server.PREFIX + '/grid.html')89 t.is(response.status(), 200)90 }91)92test.serial(93 'Page.goto should navigate to empty page with networkidle0',94 async t => {95 const { page, server } = t.context96 const response = await page.goto(server.EMPTY_PAGE, {97 waitUntil: 'networkidle0'98 })99 t.is(response.status(), 200)100 }101)102test.serial(103 'Page.goto should navigate to empty page with networkidle2',104 async t => {105 const { page, server } = t.context106 const response = await page.goto(server.EMPTY_PAGE, {107 waitUntil: 'networkidle2'108 })109 t.is(response.status(), 200)110 }111)112test.serial('Page.goto should fail when navigating to bad url', async t => {113 const { page, server } = t.context114 let error = null115 await page.goto('asdfasdf').catch(e => (error = e))116 t.true(error.message.includes('Cannot navigate to invalid URL'))117})118test.serial('Page.goto should fail when navigating to bad SSL', async t => {119 const { page, httpsServer } = t.context120 // Make sure that network events do not emit 'undefined'.121 // @see https://crbug.com/750469122 page.on('request', request => t.truthy(request))123 page.on('requestfinished', request => t.truthy(request))124 page.on('requestfailed', request => t.truthy(request))125 let error = null126 await page.goto(httpsServer.EMPTY_PAGE).catch(e => (error = e))127 t.true(error.message.includes('net::ERR_CERT_AUTHORITY_INVALID'))128})129test.serial(130 'Page.goto should fail when navigating to bad SSL after redirects',131 async t => {132 const { page, server, httpsServer } = t.context133 let error = null134 await page135 .goto(httpsServer.PREFIX + '/redirect/1.html')136 .catch(e => (error = e))137 t.true(error.message.includes('net::ERR_CERT_AUTHORITY_INVALID'))138 }139)140test.serial(141 'Page.goto should throw if networkidle is passed as an option',142 async t => {143 const { page, server } = t.context144 let error = null145 await page146 .goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' })147 .catch(err => (error = err))148 t.true(149 error.message.includes('"networkidle" option is no longer supported')150 )151 }152)153test.serial(154 'Page.goto should fail when main resources failed to load',155 async t => {156 const { page, server } = t.context157 let error = null158 await page159 .goto('http://localhost:44123/non-existing-url')160 .catch(e => (error = e))161 t.true(error.message.includes('net::ERR_CONNECTION_REFUSED'))162 }163)164test.serial(165 'Page.goto should fail when exceeding maximum navigation timeout',166 async t => {167 const { page, server } = t.context168 // Hang for request to the empty.html169 let error = null170 await page171 .goto(server.PREFIX + '/longTimeJack', {172 timeout: 1173 })174 .catch(e => (error = e))175 t.true(error.message.includes('Navigation Timeout Exceeded: 1ms'))176 t.true(error instanceof TimeoutError)177 }178)179test.serial(180 'Page.goto should fail when exceeding default maximum navigation timeout',181 async t => {182 const { page, server } = t.context183 // Hang for request to the empty.html184 let error = null185 page.setDefaultNavigationTimeout(1)186 await page.goto(server.PREFIX + '/longTimeJack').catch(e => (error = e))187 t.true(error.message.includes('Navigation Timeout Exceeded: 1ms'))188 t.true(error instanceof TimeoutError)189 }190)191test.serial(192 'Page.goto should fail when exceeding default maximum timeout',193 async t => {194 const { page, server } = t.context195 // Hang for request to the empty.html196 let error = null197 page.setDefaultTimeout(1)198 await page.goto(server.PREFIX + '/longTimeJack').catch(e => (error = e))199 t.true(error.message.includes('Navigation Timeout Exceeded: 1ms'))200 t.true(error instanceof TimeoutError)201 }202)203test.serial(204 'Page.goto should prioritize default navigation timeout over default timeout',205 async t => {206 const { page, server } = t.context207 // Hang for request to the empty.html208 let error = null209 page.setDefaultTimeout(0)210 page.setDefaultNavigationTimeout(1)211 await page.goto(server.PREFIX + '/longTimeJack').catch(e => (error = e))212 t.true(error.message.includes('Navigation Timeout Exceeded: 1ms'))213 t.true(error instanceof TimeoutError)214 }215)216test.serial('Page.goto should disable timeout when its set to 0', async t => {217 const { page, server } = t.context218 let error = null219 let loaded = false220 page.once('load', () => (loaded = true))221 await page222 .goto(server.PREFIX + '/grid.html', { timeout: 0, waitUntil: ['load'] })223 .catch(e => (error = e))224 t.falsy(error)225 t.true(loaded)226})227test.serial('Page.goto should work when navigating to valid url', async t => {228 const { page, server } = t.context229 const response = await page.goto(server.EMPTY_PAGE)230 t.true(response.ok())231})232test.serial('Page.goto should work when navigating to data url', async t => {233 const { page, server } = t.context234 const response = await page.goto('data:text/html,hello')235 t.true(response.ok())236})237test.serial('Page.goto should work when navigating to 404', async t => {238 const { page, server } = t.context239 const response = await page.goto(server.PREFIX + '/not-found')240 t.false(response.ok())241 t.is(response.status(), 404)242})243test.serial(244 'Page.goto should return last response in redirect chain',245 async t => {246 const { page, server } = t.context247 const response = await page.goto(server.PREFIX + '/redirect2/1.html')248 t.true(response.ok())249 t.is(response.url(), server.EMPTY_PAGE)250 }251)252test.serial(253 'Page.goto should wait for network idle to succeed navigation',254 async t => {255 const { page, server } = t.context256 await page.goto(server.PREFIX + '/networkidle.html', {257 waitUntil: 'networkidle0'258 }) // Track when the navigation gets completed.259 t.deepEqual(await page.evaluate(() => window.fun), [260 { n: '1' },261 { n: '2' },262 { n: '3' },263 { n: '4' }264 ])265 }266)267test.serial(268 'Page.goto should not leak listeners during navigation',269 async t => {270 const { page, server } = t.context271 let warning = null272 const warningHandler = w => (warning = w)273 process.on('warning', warningHandler)274 for (let i = 0; i < 20; ++i) await page.goto(server.EMPTY_PAGE)275 process.removeListener('warning', warningHandler)276 t.falsy(warning)277 }278)279test.serial(280 'Page.goto should not leak listeners during bad navigation',281 async t => {282 const { page, server } = t.context283 let warning = null284 const warningHandler = w => (warning = w)285 process.on('warning', warningHandler)286 for (let i = 0; i < 20; ++i)287 await page.goto('asdf').catch(e => {288 /* swallow navigation error */289 })290 process.removeListener('warning', warningHandler)291 t.falsy(warning)292 }293)294test.serial(295 'Page.goto should not leak listeners during navigation of 11 pages',296 async t => {297 const { page, context, server } = t.context298 let warning = null299 const warningHandler = w => (warning = w)300 process.on('warning', warningHandler)301 await Promise.all(302 [...Array(20)].map(async () => {303 const page = await context.newPage()304 await page.goto(server.EMPTY_PAGE)305 await page.close()306 })307 )308 process.removeListener('warning', warningHandler)309 t.falsy(warning)310 }311)312test.serial(313 'Page.goto should navigate to dataURL and fire dataURL requests',314 async t => {315 const { page, server } = t.context316 const requests = []317 page.on(318 'request',319 request => !utils.isFavicon(request) && requests.push(request)320 )321 const dataURL = 'data:text/html,<div>yo</div>'322 const response = await page.goto(dataURL)323 t.is(response.status(), 200)324 t.is(requests.length, 1)325 t.is(requests[0].url(), dataURL)326 }327)328test.serial(329 'Page.goto should navigate to URL with hash and fire requests with hash',330 async t => {331 const { page, server } = t.context332 const requests = []333 page.on(334 'request',335 request => !utils.isFavicon(request) && requests.push(request)336 )337 const response = await page.goto(server.EMPTY_PAGE + '#hash')338 t.is(response.status(), 200)339 t.is(response.url(), server.EMPTY_PAGE)340 t.is(requests.length, 1)341 t.is(requests[0].url(), server.EMPTY_PAGE + '#hash')342 }343)344test.serial('Page.goto should work with self requesting page', async t => {345 const { page, server } = t.context346 const response = await page.goto(server.PREFIX + '/self-request.html')347 t.is(response.status(), 200)348 t.true(response.url().includes('self-request.html'))349})350test.serial(351 'Page.goto should fail when navigating and show the url at the error message',352 async t => {353 const { page, server, httpsServer } = t.context354 const url = httpsServer.PREFIX + '/redirect/1.html'355 let error = null356 try {357 await page.goto(url)358 } catch (e) {359 error = e360 }361 t.true(error.message.includes(url))362 }363)364test.serial('Page.goto should send referer', async t => {365 const { page, server } = t.context366 const [request1, request2] = await Promise.all([367 server.waitForRequest('/grid.html'),368 server.waitForRequest('/digits/1.png'),369 page.goto(server.PREFIX + '/grid.html', {370 referer: 'http://google.com/'371 })372 ])373 t.is(request1.headers['referer'], 'http://google.com/')374 // Make sure subresources do not inherit referer.375 t.is(request2.headers['referer'], server.PREFIX + '/grid.html')376})377test.serial('Page.waitForNavigation should work', async t => {378 const { page, server } = t.context379 await page.goto(server.EMPTY_PAGE)380 const [response] = await Promise.all([381 page.waitForNavigation(),382 page.evaluate(383 url => (window.location.href = url),384 server.PREFIX + '/grid.html'385 )386 ])387 t.true(response.ok())388 t.true(response.url().includes('grid.html'))389})390test.serial(391 'Page.waitForNavigation should work with both domcontentloaded and load',392 async t => {393 const { page, server } = t.context394 const navigationPromise = page.goto(server.PREFIX + '/one-style.html')395 const domContentLoadedPromise = page.waitForNavigation({396 waitUntil: 'domcontentloaded'397 })398 let bothFired = false399 const bothFiredPromise = page400 .waitForNavigation({401 waitUntil: ['load', 'domcontentloaded']402 })403 .then(() => (bothFired = true))404 await server.waitForRequest('/one-style.css')405 await domContentLoadedPromise406 t.false(bothFired)407 await bothFiredPromise408 await navigationPromise409 }410)411test.serial(412 'Page.waitForNavigation should work with clicking on anchor links',413 async t => {414 const { page, server } = t.context415 await page.goto(server.EMPTY_PAGE)416 await page.setContent(`<a href='#foobar'>foobar</a>`)417 const [response] = await Promise.all([418 page.waitForNavigation(),419 page.click('a')420 ])421 t.falsy(response)422 t.is(page.url(), server.EMPTY_PAGE + '#foobar')423 }424)425test.serial(426 'Page.waitForNavigation should work with history.pushState()',427 async t => {428 const { page, server } = t.context429 await page.goto(server.EMPTY_PAGE)430 await page.setContent(`431 <a onclick='javascript:pushState()'>SPA</a>432 <script>433 function pushState() { history.pushState({}, '', 'wow.html') }434 </script>435 `)436 const [response] = await Promise.all([437 page.waitForNavigation(),438 page.click('a')439 ])440 t.falsy(response)441 t.is(page.url(), server.PREFIX + '/wow.html')442 }443)444test.serial(445 'Page.waitForNavigation should work with history.replaceState()',446 async t => {447 const { page, server } = t.context448 await page.goto(server.EMPTY_PAGE)449 await page.setContent(`450 <a onclick='javascript:replaceState()'>SPA</a>451 <script>452 function replaceState() { history.replaceState({}, '', '/replaced.html') }453 </script>454 `)455 const [response] = await Promise.all([456 page.waitForNavigation(),457 page.click('a')458 ])459 t.falsy(response)460 t.is(page.url(), server.PREFIX + '/replaced.html')461 }462)463test.serial(464 'Page.waitForNavigation should work with DOM history.back()/history.forward()',465 async t => {466 const { page, server } = t.context467 await page.goto(server.EMPTY_PAGE)468 await page.setContent(`469 <a id=back onclick='javascript:goBack()'>back</a>470 <a id=forward onclick='javascript:goForward()'>forward</a>471 <script>472 function goBack() { history.back(); }473 function goForward() { history.forward(); }474 history.pushState({}, '', '/first.html');475 history.pushState({}, '', '/second.html');476 </script>477 `)478 t.is(page.url(), server.PREFIX + '/second.html')479 const [backResponse] = await Promise.all([480 page.waitForNavigation(),481 page.click('a#back')482 ])483 t.falsy(backResponse)484 t.is(page.url(), server.PREFIX + '/first.html')485 const [forwardResponse] = await Promise.all([486 page.waitForNavigation(),487 page.click('a#forward')488 ])489 t.falsy(forwardResponse)490 t.is(page.url(), server.PREFIX + '/second.html')491 }492)493test.serial(494 'Page.waitForNavigation should work when subframe issues window.stop()',495 async t => {496 const { page, server } = t.context497 const navigationPromise = page.goto(498 server.PREFIX + '/frames/subFrameLongTimeJack.html'499 )500 const frame = await utils.waitEvent(page, 'frameattached')501 await new Promise(fulfill => {502 page.on('framenavigated', f => {503 if (f === frame) fulfill()504 })505 })506 await Promise.all([frame.evaluate(() => window.stop()), navigationPromise])507 t.pass()508 }509)510test.serial('Page.goBack should work', async t => {511 const { page, server } = t.context512 await page.goto(server.EMPTY_PAGE)513 await page.goto(server.PREFIX + '/grid.html')514 let response = await page.goBack()515 t.true(response.ok())516 t.true(response.url().includes(server.EMPTY_PAGE))517 response = await page.goForward()518 t.true(response.ok())519 t.true(response.url().includes('/grid.html'))520 response = await page.goForward()521 t.falsy(response)522})523test.serial('Page.goBack should work with HistoryAPI', async t => {524 const { page, server } = t.context525 await page.goto(server.EMPTY_PAGE)526 await page.evaluate(() => {527 history.pushState({}, '', '/first.html')528 history.pushState({}, '', '/second.html')529 })530 t.is(page.url(), server.PREFIX + '/second.html')531 await page.goBack()532 t.is(page.url(), server.PREFIX + '/first.html')533 await page.goBack()534 t.is(page.url(), server.EMPTY_PAGE)535 await page.goForward()536 t.is(page.url(), server.PREFIX + '/first.html')537})538test.serial('Frame.goto should navigate subframes', async t => {539 const { page, server } = t.context540 await page.goto(server.PREFIX + '/frames/one-frame.html')541 t.true(542 page543 .frames()[0]544 .url()545 .includes('/frames/one-frame.html')546 )547 t.true(548 page549 .frames()[1]550 .url()551 .includes('/frames/frame.html')552 )553 const response = await page.frames()[1].goto(server.EMPTY_PAGE)554 t.true(response.ok())555 t.is(response.frame(), page.frames()[1])556})557test.serial('Frame.goto should reject when frame detaches', async t => {558 const { page, server } = t.context559 await page.goto(server.PREFIX + '/frames/nested-frames.html')560 const frames = page.frames()561 t.true(frames.length > 0)562 const navigationPromise = frames[1]563 .goto(server.PREFIX + '/longTimeJack')564 .catch(e => e)565 await new Promise(resolve => setTimeout(resolve, 1000))566 // await server.waitForRequest('/longTimeJack')567 await page.$eval('iframe', frame => frame.remove())568 const error = await navigationPromise569 t.is(error.message, 'Navigating frame was detached')570})571test.serial(572 'Frame.goto should return matching responses',573 async t => {574 const { page, server } = t.context575 // Disable cache: otherwise, chromium will cache similar requests.576 await page.setCacheEnabled(false)577 await page.goto(server.EMPTY_PAGE) // Attach three frames.578 const frames = await Promise.all([579 utils.attachFrame(page, 'frame1', server.EMPTY_PAGE),580 utils.attachFrame(page, 'frame2', server.EMPTY_PAGE),581 utils.attachFrame(page, 'frame3', server.EMPTY_PAGE)582 ]) // Navigate all frames to the same URL.583 const navigations = []584 const serverResponseTexts = ['AAA', 'BBB', 'CCC']585 for (let i = 0; i < 3; ++i) {586 navigations.push(587 frames[i].goto(`${server.PREFIX}/${serverResponseTexts[i]}`)588 )589 }590 for (const i of [1, 2, 0]) {591 const response = await navigations[i]592 t.is(response.frame(), frames[i])593 t.is(await response.text(), serverResponseTexts[i])594 }595 }596)597test.serial('Frame.waitForNavigation should work', async t => {598 const { page, server } = t.context599 await page.goto(server.PREFIX + '/frames/one-frame.html')600 const frame = page.frames()[1]601 const [response] = await Promise.all([602 frame.waitForNavigation(),603 frame.evaluate(604 url => (window.location.href = url),605 server.PREFIX + '/grid.html'606 )607 ])608 t.true(response.ok())609 t.true(response.url().includes('grid.html'))610 t.is(response.frame(), frame)611 t.true(page.url().includes('/frames/one-frame.html'))612})613test.serial(614 'Frame.waitForNavigation should resolve when frame detaches',615 async t => {616 const { page, server } = t.context617 await page.goto(server.PREFIX + '/frames/nested-frames.html')618 const frame = page.frames()[1]619 let error = null620 const navigationPromise = frame.waitForNavigation().catch(e => (error = e))621 await Promise.all([622 server.waitForRequest('/longTimeJack'),623 frame.evaluate(() => (window.location = '/longTimeJack'))624 ])625 await page.$eval('iframe', frame => frame.remove())626 await navigationPromise627 t.is(error.message, 'Navigating frame was detached')628 }629)630test.serial('Page.reload should work', async t => {631 const { page, server } = t.context632 await page.goto(server.EMPTY_PAGE)633 await page.evaluate(() => (window._foo = 10))634 await page.reload()635 const testResult = await page.evaluate(() => window._foo)636 t.falsy(testResult)...
network.js
Source:network.js
...30 page.on(31 'request',32 request => !utils.isFavicon(request) && requests.push(request)33 )34 await page.goto(server.EMPTY_PAGE)35 t.is(requests.length, 1)36 }37)38test.serial('Page.Events.Request should fire for iframes', async t => {39 const { page, server } = t.context40 const requests = []41 page.on(42 'request',43 request => !utils.isFavicon(request) && requests.push(request)44 )45 await page.goto(server.EMPTY_PAGE)46 await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE)47 t.is(requests.length, 2)48})49test.serial('Page.Events.Request should fire for fetches', async t => {50 const { page, server } = t.context51 const requests = []52 page.on(53 'request',54 request => !utils.isFavicon(request) && requests.push(request)55 )56 await page.goto(server.EMPTY_PAGE)57 await page.evaluate(() => fetch('/empty.html'))58 t.is(requests.length, 2)59})60test.serial(61 'Request.frame should work for main frame navigation request',62 async t => {63 const { page, server } = t.context64 const requests = []65 page.on(66 'request',67 request => !utils.isFavicon(request) && requests.push(request)68 )69 await page.goto(server.EMPTY_PAGE)70 t.is(requests.length, 1)71 t.is(requests[0].frame(), page.mainFrame())72 }73)74test.serial(75 'Request.frame should work for subframe navigation request',76 async t => {77 const { page, server } = t.context78 await page.goto(server.EMPTY_PAGE)79 const requests = []80 page.on(81 'request',82 request => !utils.isFavicon(request) && requests.push(request)83 )84 await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE)85 t.is(requests.length, 1)86 t.is(requests[0].frame(), page.frames()[1])87 }88)89test.serial('Request.frame should work for fetch requests', async t => {90 const { page, server } = t.context91 await page.goto(server.EMPTY_PAGE)92 let requests = []93 page.on(94 'request',95 request => !utils.isFavicon(request) && requests.push(request)96 )97 await page.evaluate(() => fetch('/digits/1.png'))98 requests = requests.filter(request => !request.url().includes('favicon'))99 t.is(requests.length, 1)100 t.is(requests[0].frame(), page.mainFrame())101})102test.serial('Request.headers should work', async t => {103 const { page, server } = t.context104 const response = await page.goto(server.EMPTY_PAGE)105 t.true(106 response107 .request()108 .normalizedHeaders()109 ['user-agent'].includes('Chrome')110 )111})112test.serial('Response.headers should work', async t => {113 const { page, server } = t.context114 const response = await page.goto(server.EMPTY_FOO_BAR_HEADERS_PAGE)115 t.is(response.headers()['foo'], 'bar')116})117test.serial(118 'Response.fromCache should return |false| for non-cached content',119 async t => {120 const { page, server } = t.context121 const response = await page.goto(server.EMPTY_FOO_BAR_HEADERS_PAGE)122 t.false(response.fromCache())123 }124)125test.serial('Response.fromCache should work', async t => {126 const { page, server } = t.context127 const responses = new Map()128 page.on(129 'response',130 r =>131 !utils.isFavicon(r.request()) &&132 responses.set(133 r134 .url()135 .split('/')136 .pop(),137 r138 )139 )140 // Load and re-load to make sure it's cached.141 await page.goto(server.PREFIX + '/cached/one-style.html')142 await page.waitFor(1000)143 await page.reload()144 t.is(responses.size, 2)145 t.true([200, 304].includes(responses.get('one-style.css').status()))146})147test.serial(148 'Response.fromServiceWorker should return |false| for non-service-worker content',149 async t => {150 const { page, server } = t.context151 const response = await page.goto(server.EMPTY_PAGE)152 t.false(response.fromServiceWorker())153 }154)155test.serial(156 'Response.fromServiceWorker Response.fromServiceWorker',157 async t => {158 const { page, server } = t.context159 const responses = new Map()160 page.on('response', r =>161 responses.set(162 r163 .url()164 .split('/')165 .pop(),166 r167 )168 )169 // Load and re-load to make sure serviceworker is installed and running.170 await page.goto(server.PREFIX + '/serviceworkers/fetch/sw.html', {171 waitUntil: 'networkidle2'172 })173 await page.evaluate(async () => await window.activationPromise)174 await page.reload()175 t.true([2, 3].includes(responses.size))176 t.is(responses.get('sw.html').status(), 200)177 t.true(responses.get('sw.html').fromServiceWorker())178 t.is(responses.get('style.css').status(), 200)179 t.true(responses.get('style.css').fromServiceWorker())180 }181)182test.serial('Request.postData should work', async t => {183 const { page, server } = t.context184 await page.goto(server.EMPTY_PAGE)185 let request = null186 page.on('request', r => (request = r))187 await page.evaluate(() =>188 fetch('./post', {189 method: 'POST',190 body: JSON.stringify({191 foo: 'bar'192 })193 })194 )195 t.truthy(request)196 t.is(request.postData(), '{"foo":"bar"}')197})198test.serial(199 'Request.postData should be |undefined| when there is no post data',200 async t => {201 const { page, server } = t.context202 const response = await page.goto(server.EMPTY_PAGE)203 t.falsy(response.request().postData())204 }205)206test.serial('Response.text should work', async t => {207 const { page, server } = t.context208 const response = await page.goto(server.PREFIX + '/simple.json')209 t.is(await response.text(), '{"foo": "bar"}\n')210})211test.serial('Response.text should return uncompressed text', async t => {212 const { page, server } = t.context213 await page.goto(server.EMPTY_PAGE)214 const [response] = await Promise.all([215 page.waitForResponse(server.PREFIX + '/simple.json.gz'),216 page.evaluate(url => fetch(url), server.PREFIX + '/simple.json.gz')217 ])218 t.is(response.headers()['content-encoding'], 'gzip')219 t.is(await response.text(), '{"foo": "bar"}\n')220})221test.serial(222 'Response.text should throw when requesting body of redirected response',223 async t => {224 const { page, server } = t.context225 const response = await page.goto(server.PREFIX + '/foo.html')226 const redirectChain = response.request().redirectChain()227 t.is(redirectChain.length, 1)228 const redirected = redirectChain[0].response()229 t.is(redirected.status(), 302)230 let error = null231 await redirected.text().catch(e => (error = e))232 t.true(233 error.message.includes(234 'Response body is unavailable for redirect responses'235 )236 )237 }238)239test.serial('Response.text should wait until response completes', async t => {240 const { page, server } = t.context241 await page.goto(server.EMPTY_PAGE) // Setup server to trap request.242 server.slowStreamSpeed(300)243 const [pageResponse] = await Promise.all([244 page.waitForResponse(r => !utils.isFavicon(r.request())),245 page.evaluate(() =>246 fetch('./get-slow', {247 method: 'GET'248 })249 ),250 server.waitForRequest('/get-slow')251 ])252 t.truthy(pageResponse)253 t.is(pageResponse.status(), 200)254 t.is(await pageResponse.text(), 'hello world!')255})256test.serial('Response.json should work', async t => {257 const { page, server } = t.context258 const response = await page.goto(server.PREFIX + '/simple.json')259 t.deepEqual(await response.json(), {260 foo: 'bar'261 })262})263test.serial('Response.buffer should work', async t => {264 const { page, server } = t.context265 const response = await page.goto(server.PREFIX + '/pptr.png')266 const imageBuffer = await fs.readFile(utils.assetPath('pptr.png'))267 const responseBuffer = await response.buffer()268 t.true(responseBuffer.equals(imageBuffer))269})270test.serial('Response.buffer should work with compression', async t => {271 const { page, server } = t.context272 await page.goto(server.EMPTY_PAGE)273 const [response] = await Promise.all([274 page.waitForResponse(res => res.url().endsWith('/pptr.png.gz')),275 page.evaluate(async toBeFetched => {276 await fetch(toBeFetched).catch(() => {})277 }, server.PREFIX + '/pptr.png.gz')278 ])279 const imageBuffer = await fs.readFile(utils.assetPath('pptr.png'))280 const responseBuffer = await response.buffer()281 t.true(responseBuffer.equals(imageBuffer))282})283test.serial('Response.statusText should work', async t => {284 const { page, server } = t.context285 const response = await page.goto(server.PREFIX + '/cool')286 t.is(response.statusText(), 'cool!')287})288test.serial('Network Events Page.Events.Request', async t => {289 const { page, server } = t.context290 const requests = []291 page.on('request', request => requests.push(request))292 await page.goto(server.EMPTY_PAGE)293 t.is(requests.length, 1)294 t.is(requests[0].url(), server.EMPTY_PAGE)295 t.is(requests[0].resourceType(), 'document')296 t.is(requests[0].method(), 'GET')297 t.truthy(requests[0].response())298 t.true(requests[0].frame() === page.mainFrame())299 t.is(requests[0].frame().url(), server.EMPTY_PAGE)300})301test.serial('Network Events Page.Events.Response', async t => {302 const { page, server } = t.context303 const responses = []304 page.on('response', response => responses.push(response))305 await page.goto(server.EMPTY_PAGE)306 t.is(responses.length, 1)307 t.is(responses[0].url(), server.EMPTY_PAGE)308 t.is(responses[0].status(), 200)309 t.true(responses[0].ok())310 t.truthy(responses[0].request())311 const remoteAddress = responses[0].remoteAddress()312 // Either IPv6 or IPv4, depending on environment.313 t.true(remoteAddress.ip.includes('::1') || remoteAddress.ip === '127.0.0.1')314 t.is(remoteAddress.port, server.PORT)315})316test.serial('Network Events Page.Events.RequestFailed', async t => {317 const { page, server } = t.context318 await page.setRequestInterception(true)319 page.on('request', request => {320 if (request.url().endsWith('css')) request.abort()321 else request.continue()322 })323 const failedRequests = []324 page.on('requestfailed', request => failedRequests.push(request))325 await page.goto(server.PREFIX + '/one-style.html')326 t.is(failedRequests.length, 1)327 t.true(failedRequests[0].url().includes('one-style.css'))328 t.falsy(failedRequests[0].response())329 t.is(failedRequests[0].resourceType(), 'stylesheet')330 t.is(failedRequests[0].failure().errorText, 'net::ERR_FAILED')331 t.truthy(failedRequests[0].frame())332})333test.serial('Network Events Page.Events.RequestFinished', async t => {334 const { page, server } = t.context335 const requests = []336 page.on('requestfinished', request => requests.push(request))337 await page.goto(server.EMPTY_PAGE)338 t.is(requests.length, 1)339 t.is(requests[0].url(), server.EMPTY_PAGE)340 t.truthy(requests[0].response())341 t.true(requests[0].frame() === page.mainFrame())342 t.is(requests[0].frame().url(), server.EMPTY_PAGE)343})344test.serial('Network Events should fire events in proper order', async t => {345 const { page, server } = t.context346 const events = []347 page.on('request', request => events.push('request'))348 page.on('response', response => events.push('response'))349 page.on('requestfinished', request => events.push('requestfinished'))350 await page.goto(server.EMPTY_PAGE)351 t.deepEqual(events, ['request', 'response', 'requestfinished'])352})353test.serial('Network Events should support redirects', async t => {354 const { page, server } = t.context355 const events = []356 page.on('request', request =>357 events.push(`${request.method()} ${request.url()}`)358 )359 page.on('response', response =>360 events.push(`${response.status()} ${response.url()}`)361 )362 page.on('requestfinished', request => events.push(`DONE ${request.url()}`))363 page.on('requestfailed', request => events.push(`FAIL ${request.url()}`))364 const FOO_URL = server.PREFIX + '/foo.html'365 const response = await page.goto(FOO_URL)366 t.deepEqual(events, [367 `GET ${FOO_URL}`,368 `302 ${FOO_URL}`,369 `DONE ${FOO_URL}`,370 `GET ${server.EMPTY_PAGE}`,371 `200 ${server.EMPTY_PAGE}`,372 `DONE ${server.EMPTY_PAGE}`373 ])374 // Check redirect chain375 const redirectChain = response.request().redirectChain()376 t.is(redirectChain.length, 1)377 t.true(redirectChain[0].url().includes('/foo.html'))378 t.is(redirectChain[0].response().remoteAddress().port, server.PORT)379})380test.serial('Request.isNavigationRequest should work', async t => {381 const { page, server } = t.context382 const requests = new Map()383 page.on('request', request =>384 requests.set(385 request386 .url()387 .split('/')388 .pop(),389 request390 )391 )392 await page.goto(server.PREFIX + '/rrredirect')393 t.true(requests.get('rrredirect').isNavigationRequest())394 t.true(requests.get('one-frame.html').isNavigationRequest())395 t.true(requests.get('frame.html').isNavigationRequest())396 t.false(requests.get('script.js').isNavigationRequest())397 t.false(requests.get('style.css').isNavigationRequest())398})399test.serial(400 'Request.isNavigationRequest should work with request interception',401 async t => {402 const { page, server } = t.context403 const requests = new Map()404 page.on('request', request => {405 requests.set(406 request407 .url()408 .split('/')409 .pop(),410 request411 )412 request.continue()413 })414 await page.setRequestInterception(true)415 await page.goto(server.PREFIX + '/rrredirect')416 t.true(requests.get('rrredirect').isNavigationRequest())417 t.true(requests.get('one-frame.html').isNavigationRequest())418 t.true(requests.get('frame.html').isNavigationRequest())419 t.false(requests.get('script.js').isNavigationRequest())420 t.false(requests.get('style.css').isNavigationRequest())421 }422)423test.serial(424 'Request.isNavigationRequest should work when navigating to image',425 async t => {426 const { page, server } = t.context427 const requests = []428 page.on('request', request => requests.push(request))429 await page.goto(server.PREFIX + '/pptr.png')430 t.true(requests[0].isNavigationRequest())431 }432)433test.serial('Page.setExtraHTTPHeaders should work', async t => {434 const { page, server } = t.context435 await page.setExtraHTTPHeaders({436 foo: 'bar'437 })438 const [request] = await Promise.all([439 page.waitForRequest(server.EMPTY_PAGE),440 page.goto(server.EMPTY_PAGE)441 ])442 t.is(request.headers()['foo'], 'bar')443})444test.serial(445 'Page.setExtraHTTPHeaders should throw for non-string header values',446 async t => {447 const { page, server } = t.context448 let error = null449 try {450 await page.setExtraHTTPHeaders({451 foo: 1452 })453 } catch (e) {454 error = e455 }456 t.is(457 error.message,458 'Expected value of header "foo" to be String, but "number" is found.'459 )460 }461)462test.serial('Page.authenticate should work', async t => {463 t.timeout(10000)464 const { page, server } = t.context465 await page.authenticate({466 username: 'user',467 password: 'pass'468 })469 let response = await page.goto(server.AUTH_EMPTY_PAGE)470 t.is(response.status(), 200)471})472test.serial('Page.authenticate should fail if wrong credentials', async t => {473 const { page, server } = t.context474 await page.authenticate({475 username: 'foo',476 password: 'bar'477 })478 const response = await page.goto(server.AUTH_EMPTY_PAGE_2)479 t.is(response.status(), 401)480})481test.serial(482 'Page.authenticate should allow disable authentication',483 async t => {484 const { page, server } = t.context485 // Use unique user/password since Chrome caches credentials per origin.486 await page.authenticate({487 username: 'user3',488 password: 'pass3'489 })490 let response = await page.goto(server.AUTH_EMPTY_PAGE_3)491 t.is(response.status(), 200)492 await page.authenticate(null) // Navigate to a different origin to bust Chrome's credential caching.493 response = await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html')494 t.is(response.status(), 200)495 }...
coverage.spec.js
Source:coverage.spec.js
...25 setupTestPageAndContextHooks();26 it('should work', async () => {27 const { page, server } = getTestState();28 await page.coverage.startJSCoverage();29 await page.goto(server.PREFIX + '/jscoverage/simple.html', {30 waitUntil: 'networkidle0',31 });32 const coverage = await page.coverage.stopJSCoverage();33 expect(coverage.length).toBe(1);34 expect(coverage[0].url).toContain('/jscoverage/simple.html');35 expect(coverage[0].ranges).toEqual([36 { start: 0, end: 17 },37 { start: 35, end: 61 },38 ]);39 });40 it('should report sourceURLs', async () => {41 const { page, server } = getTestState();42 await page.coverage.startJSCoverage();43 await page.goto(server.PREFIX + '/jscoverage/sourceurl.html');44 const coverage = await page.coverage.stopJSCoverage();45 expect(coverage.length).toBe(1);46 expect(coverage[0].url).toBe('nicename.js');47 });48 it('should ignore eval() scripts by default', async () => {49 const { page, server } = getTestState();50 await page.coverage.startJSCoverage();51 await page.goto(server.PREFIX + '/jscoverage/eval.html');52 const coverage = await page.coverage.stopJSCoverage();53 expect(coverage.length).toBe(1);54 });55 it("shouldn't ignore eval() scripts if reportAnonymousScripts is true", async () => {56 const { page, server } = getTestState();57 await page.coverage.startJSCoverage({ reportAnonymousScripts: true });58 await page.goto(server.PREFIX + '/jscoverage/eval.html');59 const coverage = await page.coverage.stopJSCoverage();60 expect(61 coverage.find((entry) => entry.url.startsWith('debugger://'))62 ).not.toBe(null);63 expect(coverage.length).toBe(2);64 });65 it('should ignore pptr internal scripts if reportAnonymousScripts is true', async () => {66 const { page, server } = getTestState();67 await page.coverage.startJSCoverage({ reportAnonymousScripts: true });68 await page.goto(server.EMPTY_PAGE);69 await page.evaluate('console.log("foo")');70 await page.evaluate(() => console.log('bar'));71 const coverage = await page.coverage.stopJSCoverage();72 expect(coverage.length).toBe(0);73 });74 it('should report multiple scripts', async () => {75 const { page, server } = getTestState();76 await page.coverage.startJSCoverage();77 await page.goto(server.PREFIX + '/jscoverage/multiple.html');78 const coverage = await page.coverage.stopJSCoverage();79 expect(coverage.length).toBe(2);80 coverage.sort((a, b) => a.url.localeCompare(b.url));81 expect(coverage[0].url).toContain('/jscoverage/script1.js');82 expect(coverage[1].url).toContain('/jscoverage/script2.js');83 });84 it('should report right ranges', async () => {85 const { page, server } = getTestState();86 await page.coverage.startJSCoverage();87 await page.goto(server.PREFIX + '/jscoverage/ranges.html');88 const coverage = await page.coverage.stopJSCoverage();89 expect(coverage.length).toBe(1);90 const entry = coverage[0];91 expect(entry.ranges.length).toBe(1);92 const range = entry.ranges[0];93 expect(entry.text.substring(range.start, range.end)).toBe(94 `console.log('used!');`95 );96 });97 it('should report scripts that have no coverage', async () => {98 const { page, server } = getTestState();99 await page.coverage.startJSCoverage();100 await page.goto(server.PREFIX + '/jscoverage/unused.html');101 const coverage = await page.coverage.stopJSCoverage();102 expect(coverage.length).toBe(1);103 const entry = coverage[0];104 expect(entry.url).toContain('unused.html');105 expect(entry.ranges.length).toBe(0);106 });107 it('should work with conditionals', async () => {108 const { page, server } = getTestState();109 await page.coverage.startJSCoverage();110 await page.goto(server.PREFIX + '/jscoverage/involved.html');111 const coverage = await page.coverage.stopJSCoverage();112 expect(113 JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')114 ).toBeGolden('jscoverage-involved.txt');115 });116 describe('resetOnNavigation', function () {117 it('should report scripts across navigations when disabled', async () => {118 const { page, server } = getTestState();119 await page.coverage.startJSCoverage({ resetOnNavigation: false });120 await page.goto(server.PREFIX + '/jscoverage/multiple.html');121 await page.goto(server.EMPTY_PAGE);122 const coverage = await page.coverage.stopJSCoverage();123 expect(coverage.length).toBe(2);124 });125 it('should NOT report scripts across navigations when enabled', async () => {126 const { page, server } = getTestState();127 await page.coverage.startJSCoverage(); // Enabled by default.128 await page.goto(server.PREFIX + '/jscoverage/multiple.html');129 await page.goto(server.EMPTY_PAGE);130 const coverage = await page.coverage.stopJSCoverage();131 expect(coverage.length).toBe(0);132 });133 });134 // @see https://crbug.com/990945135 xit('should not hang when there is a debugger statement', async () => {136 const { page, server } = getTestState();137 await page.coverage.startJSCoverage();138 await page.goto(server.EMPTY_PAGE);139 await page.evaluate(() => {140 debugger; // eslint-disable-line no-debugger141 });142 await page.coverage.stopJSCoverage();143 });144 });145 describeChromeOnly('CSSCoverage', function () {146 setupTestBrowserHooks();147 setupTestPageAndContextHooks();148 it('should work', async () => {149 const { page, server } = getTestState();150 await page.coverage.startCSSCoverage();151 await page.goto(server.PREFIX + '/csscoverage/simple.html');152 const coverage = await page.coverage.stopCSSCoverage();153 expect(coverage.length).toBe(1);154 expect(coverage[0].url).toContain('/csscoverage/simple.html');155 expect(coverage[0].ranges).toEqual([{ start: 1, end: 22 }]);156 const range = coverage[0].ranges[0];157 expect(coverage[0].text.substring(range.start, range.end)).toBe(158 'div { color: green; }'159 );160 });161 it('should report sourceURLs', async () => {162 const { page, server } = getTestState();163 await page.coverage.startCSSCoverage();164 await page.goto(server.PREFIX + '/csscoverage/sourceurl.html');165 const coverage = await page.coverage.stopCSSCoverage();166 expect(coverage.length).toBe(1);167 expect(coverage[0].url).toBe('nicename.css');168 });169 it('should report multiple stylesheets', async () => {170 const { page, server } = getTestState();171 await page.coverage.startCSSCoverage();172 await page.goto(server.PREFIX + '/csscoverage/multiple.html');173 const coverage = await page.coverage.stopCSSCoverage();174 expect(coverage.length).toBe(2);175 coverage.sort((a, b) => a.url.localeCompare(b.url));176 expect(coverage[0].url).toContain('/csscoverage/stylesheet1.css');177 expect(coverage[1].url).toContain('/csscoverage/stylesheet2.css');178 });179 it('should report stylesheets that have no coverage', async () => {180 const { page, server } = getTestState();181 await page.coverage.startCSSCoverage();182 await page.goto(server.PREFIX + '/csscoverage/unused.html');183 const coverage = await page.coverage.stopCSSCoverage();184 expect(coverage.length).toBe(1);185 expect(coverage[0].url).toBe('unused.css');186 expect(coverage[0].ranges.length).toBe(0);187 });188 it('should work with media queries', async () => {189 const { page, server } = getTestState();190 await page.coverage.startCSSCoverage();191 await page.goto(server.PREFIX + '/csscoverage/media.html');192 const coverage = await page.coverage.stopCSSCoverage();193 expect(coverage.length).toBe(1);194 expect(coverage[0].url).toContain('/csscoverage/media.html');195 expect(coverage[0].ranges).toEqual([{ start: 17, end: 38 }]);196 });197 it('should work with complicated usecases', async () => {198 const { page, server } = getTestState();199 await page.coverage.startCSSCoverage();200 await page.goto(server.PREFIX + '/csscoverage/involved.html');201 const coverage = await page.coverage.stopCSSCoverage();202 expect(203 JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')204 ).toBeGolden('csscoverage-involved.txt');205 });206 it('should ignore injected stylesheets', async () => {207 const { page } = getTestState();208 await page.coverage.startCSSCoverage();209 await page.addStyleTag({ content: 'body { margin: 10px;}' });210 // trigger style recalc211 const margin = await page.evaluate(212 () => window.getComputedStyle(document.body).margin213 );214 expect(margin).toBe('10px');215 const coverage = await page.coverage.stopCSSCoverage();216 expect(coverage.length).toBe(0);217 });218 describe('resetOnNavigation', function () {219 it('should report stylesheets across navigations', async () => {220 const { page, server } = getTestState();221 await page.coverage.startCSSCoverage({ resetOnNavigation: false });222 await page.goto(server.PREFIX + '/csscoverage/multiple.html');223 await page.goto(server.EMPTY_PAGE);224 const coverage = await page.coverage.stopCSSCoverage();225 expect(coverage.length).toBe(2);226 });227 it('should NOT report scripts across navigations', async () => {228 const { page, server } = getTestState();229 await page.coverage.startCSSCoverage(); // Enabled by default.230 await page.goto(server.PREFIX + '/csscoverage/multiple.html');231 await page.goto(server.EMPTY_PAGE);232 const coverage = await page.coverage.stopCSSCoverage();233 expect(coverage.length).toBe(0);234 });235 });236 it('should work with a recently loaded stylesheet', async () => {237 const { page, server } = getTestState();238 await page.coverage.startCSSCoverage();239 await page.evaluate(async (url) => {240 document.body.textContent = 'hello, world';241 const link = document.createElement('link');242 link.rel = 'stylesheet';243 link.href = url;244 document.head.appendChild(link);245 await new Promise((x) => (link.onload = x));...
coverage.js
Source:coverage.js
...21})22test.serial('JSCoverage should work', async t => {23 const { page, server } = t.context24 await page.coverage.startJSCoverage()25 await page.goto(server.PREFIX + '/jscoverage/simple.html', {26 waitUntil: 'networkidle0'27 })28 const coverage = await page.coverage.stopJSCoverage()29 t.is(coverage.length, 1)30 t.true(coverage[0].url.includes('/jscoverage/simple.html'))31 t.deepEqual(coverage[0].ranges, [32 { start: 0, end: 17 },33 { start: 35, end: 61 }34 ])35})36test.serial('JSCoverage should report sourceURLs', async t => {37 const { page, server } = t.context38 await page.coverage.startJSCoverage()39 await page.goto(server.PREFIX + '/jscoverage/sourceurl.html')40 const coverage = await page.coverage.stopJSCoverage()41 t.is(coverage.length, 1)42 t.is(coverage[0].url, 'nicename.js')43})44test.serial('JSCoverage should ignore eval() scripts by default', async t => {45 const { page, server } = t.context46 await page.coverage.startJSCoverage()47 await page.goto(server.PREFIX + '/jscoverage/eval.html')48 const coverage = await page.coverage.stopJSCoverage()49 t.is(coverage.length, 1)50})51test.serial(52 "JSCoverage shouldn't ignore eval() scripts if reportAnonymousScripts is true",53 async t => {54 const { page, server } = t.context55 await page.coverage.startJSCoverage({ reportAnonymousScripts: true })56 await page.goto(server.PREFIX + '/jscoverage/eval.html')57 const coverage = await page.coverage.stopJSCoverage()58 t.truthy(coverage.find(entry => entry.url.startsWith('debugger://')))59 t.is(coverage.length, 2)60 }61)62test.serial.skip(63 'JSCoverage should ignore pptr internal scripts if reportAnonymousScripts is true',64 async t => {65 const { page, server } = t.context66 await page.coverage.startJSCoverage({ reportAnonymousScripts: true })67 await page.goto(server.EMPTY_PAGE)68 await page.evaluate('console.log("foo")')69 await page.evaluate(() => console.log('bar'))70 const coverage = await page.coverage.stopJSCoverage()71 t.is(coverage.length, 0)72 }73)74test.serial('JSCoverage should report multiple scripts', async t => {75 const { page, server } = t.context76 await page.coverage.startJSCoverage()77 await page.goto(server.PREFIX + '/jscoverage/multiple.html')78 const coverage = await page.coverage.stopJSCoverage()79 t.is(coverage.length, 2)80 coverage.sort((a, b) => a.url.localeCompare(b.url))81 t.true(coverage[0].url.includes('/jscoverage/script1.js'))82 t.true(coverage[1].url.includes('/jscoverage/script2.js'))83})84test.serial('JSCoverage should report right ranges', async t => {85 const { page, server } = t.context86 await page.coverage.startJSCoverage()87 await page.goto(server.PREFIX + '/jscoverage/ranges.html')88 const coverage = await page.coverage.stopJSCoverage()89 t.is(coverage.length, 1)90 const entry = coverage[0]91 t.is(entry.ranges.length, 1)92 const range = entry.ranges[0]93 t.is(entry.text.substring(range.start, range.end), `console.log('used!');`)94})95test.serial(96 'JSCoverage should report scripts that have no coverage',97 async t => {98 const { page, server } = t.context99 await page.coverage.startJSCoverage()100 await page.goto(server.PREFIX + '/jscoverage/unused.html')101 const coverage = await page.coverage.stopJSCoverage()102 t.is(coverage.length, 1)103 const entry = coverage[0]104 t.true(entry.url.includes('unused.html'))105 t.is(entry.ranges.length, 0)106 }107)108test.serial('JSCoverage should work with conditionals', async t => {109 const { page, server } = t.context110 await page.coverage.startJSCoverage()111 await page.goto(server.PREFIX + '/jscoverage/involved.html')112 const coverage = await page.coverage.stopJSCoverage()113 t.context.toBeGolden(114 t,115 JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/'),116 'jscoverage-involved.txt'117 )118})119test.serial(120 'JSCoverage - resetOnNavigation: should report scripts across navigations when disabled',121 async t => {122 const { page, server } = t.context123 await page.coverage.startJSCoverage({ resetOnNavigation: false })124 await page.goto(server.PREFIX + '/jscoverage/multiple.html')125 await page.goto(server.EMPTY_PAGE)126 const coverage = await page.coverage.stopJSCoverage()127 t.is(coverage.length, 2)128 }129)130test.serial(131 'JSCoverage - resetOnNavigation: should NOT report scripts across navigations when enabled',132 async t => {133 const { page, server } = t.context134 await page.coverage.startJSCoverage() // Enabled by default.135 await page.goto(server.PREFIX + '/jscoverage/multiple.html')136 await page.goto(server.EMPTY_PAGE)137 const coverage = await page.coverage.stopJSCoverage()138 t.is(coverage.length, 0)139 }140)141test.serial(142 'JSCoverage should not hang when there is a debugger statement',143 async t => {144 const { page, server } = t.context145 await page.coverage.startJSCoverage()146 await page.goto(server.EMPTY_PAGE)147 await page.evaluate(`() => {148 debugger // eslint-disable-line no-debugger149 }`)150 await page.coverage.stopJSCoverage()151 t.pass()152 }153)154test.serial('CSSCoverage should work', async t => {155 const { page, server } = t.context156 await page.coverage.startCSSCoverage()157 await page.goto(server.PREFIX + '/csscoverage/simple.html')158 const coverage = await page.coverage.stopCSSCoverage()159 t.is(coverage.length, 1)160 t.true(coverage[0].url.includes('/csscoverage/simple.html'))161 t.deepEqual(coverage[0].ranges, [{ start: 1, end: 22 }])162 const range = coverage[0].ranges[0]163 t.is(164 coverage[0].text.substring(range.start, range.end),165 'div { color: green; }'166 )167})168test.serial('CSSCoverage should report sourceURLs', async t => {169 const { page, server } = t.context170 await page.coverage.startCSSCoverage()171 await page.goto(server.PREFIX + '/csscoverage/sourceurl.html')172 const coverage = await page.coverage.stopCSSCoverage()173 t.is(coverage.length, 1)174 t.is(coverage[0].url, 'nicename.css')175})176test.serial('CSSCoverage should report multiple stylesheets', async t => {177 const { page, server } = t.context178 await page.coverage.startCSSCoverage()179 await page.goto(server.PREFIX + '/csscoverage/multiple.html')180 const coverage = await page.coverage.stopCSSCoverage()181 t.is(coverage.length, 2)182 coverage.sort((a, b) => a.url.localeCompare(b.url))183 t.true(coverage[0].url.includes('/csscoverage/stylesheet1.css'))184 t.true(coverage[1].url.includes('/csscoverage/stylesheet2.css'))185})186test.serial(187 'CSSCoverage should report stylesheets that have no coverage',188 async t => {189 const { page, server } = t.context190 await page.coverage.startCSSCoverage()191 await page.goto(server.PREFIX + '/csscoverage/unused.html')192 const coverage = await page.coverage.stopCSSCoverage()193 t.is(coverage.length, 1)194 t.is(coverage[0].url, 'unused.css')195 t.is(coverage[0].ranges.length, 0)196 }197)198test.serial('CSSCoverage should work with media queries', async t => {199 const { page, server } = t.context200 await page.coverage.startCSSCoverage()201 await page.goto(server.PREFIX + '/csscoverage/media.html')202 const coverage = await page.coverage.stopCSSCoverage()203 t.is(coverage.length, 1)204 t.true(coverage[0].url.includes('/csscoverage/media.html'))205 t.deepEqual(coverage[0].ranges, [{ start: 17, end: 38 }])206})207test.serial('CSSCoverage should work with complicated usecases', async t => {208 const { page, server } = t.context209 await page.coverage.startCSSCoverage()210 await page.goto(server.PREFIX + '/csscoverage/involved.html')211 const coverage = await page.coverage.stopCSSCoverage()212 t.context.toBeGolden(213 t,214 JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/'),215 'csscoverage-involved.txt'216 )217})218test.serial('CSSCoverage should ignore injected stylesheets', async t => {219 const { page, server } = t.context220 await page.coverage.startCSSCoverage()221 await page.addStyleTag({ content: 'body { margin: 10px;}' })222 // trigger style recalc223 const margin = await page.evaluate(224 () => window.getComputedStyle(document.body).margin225 )226 t.is(margin, '10px')227 const coverage = await page.coverage.stopCSSCoverage()228 t.is(coverage.length, 0)229})230test.serial(231 'CSSCoverage - resetOnNavigation: should report stylesheets across navigations',232 async t => {233 const { page, server } = t.context234 await page.coverage.startCSSCoverage({ resetOnNavigation: false })235 await page.goto(server.PREFIX + '/csscoverage/multiple.html')236 await page.goto(server.EMPTY_PAGE)237 const coverage = await page.coverage.stopCSSCoverage()238 t.is(coverage.length, 2)239 }240)241test.serial(242 'CSSCoverage - resetOnNavigation: should NOT report scripts across navigations',243 async t => {244 const { page, server } = t.context245 await page.coverage.startCSSCoverage() // Enabled by default.246 await page.goto(server.PREFIX + '/csscoverage/multiple.html')247 await page.goto(server.EMPTY_PAGE)248 const coverage = await page.coverage.stopCSSCoverage()249 t.is(coverage.length, 0)250 }251)252test.serial(253 'CSSCoverage should work with a recently loaded stylesheet',254 async t => {255 const { page, server } = t.context256 await page.coverage.startCSSCoverage()257 await page.evaluate(async url => {258 document.body.textContent = 'hello, world'259 const link = document.createElement('link')260 link.rel = 'stylesheet'261 link.href = url...
renderers.js
Source:renderers.js
...4const run = async () => {5 const browser = await Puppeteer.launch({ headless: true });6 const page = await browser.newPage();7 await snapshot('match-id.png', async () => {8 await page.goto('http://localhost:1234/match-id');9 return await page.screenshot({ fullPage: true });10 });11 await snapshot('match-class.png', async () => {12 await page.goto('http://localhost:1234/match-class');13 return await page.screenshot({ fullPage: true });14 });15 await snapshot('match-attributes.png', async () => {16 await page.goto('http://localhost:1234/match-attributes');17 return await page.screenshot({ fullPage: true });18 });19 await snapshot('with-specificity-ascending.png', async () => {20 await page.goto('http://localhost:1234/with-specificity-ascending');21 return await page.screenshot({ fullPage: true });22 });23 await snapshot('with-specificity-descending.png', async () => {24 await page.goto('http://localhost:1234/with-specificity-descending');25 return await page.screenshot({ fullPage: true });26 });27 await snapshot('with-multiple-stylesheets.png', async () => {28 await page.goto('http://localhost:1234/with-multiple-stylesheets');29 return await page.screenshot({ fullPage: true });30 });31 await snapshot('match-nth-child-even.png', async () => {32 await page.goto('http://localhost:1234/match-nth-child-even');33 return await page.screenshot({ fullPage: true });34 });35 await snapshot('match-nth-child-odd.png', async () => {36 await page.goto('http://localhost:1234/match-nth-child-odd');37 return await page.screenshot({ fullPage: true });38 });39 await snapshot('match-nth-child-formula.png', async () => {40 await page.goto('http://localhost:1234/match-nth-child-formula');41 return await page.screenshot({ fullPage: true });42 });43 await snapshot('match-component.png', async () => {44 await page.goto('http://localhost:1234/match-component');45 return await page.screenshot({ fullPage: true });46 });47 await snapshot('with-inline-style.png', async () => {48 await page.goto('http://localhost:1234/with-inline-style');49 return await page.screenshot({ fullPage: true });50 });51 await snapshot('with-inline-style-component.png', async () => {52 await page.goto('http://localhost:1234/with-inline-style-component');53 return await page.screenshot({ fullPage: true });54 });55 await snapshot('with-fragment.png', async () => {56 await page.goto('http://localhost:1234/with-fragment');57 return await page.screenshot({ fullPage: true });58 });59 await snapshot('match-tag.png', async () => {60 await page.goto('http://localhost:1234/match-tag');61 return await page.screenshot({ fullPage: true });62 });63 await snapshot('mismatch-tag.png', async () => {64 await page.goto('http://localhost:1234/mismatch-tag');65 return await page.screenshot({ fullPage: true });66 });67 await snapshot('mismatch-tag-with-class.png', async () => {68 await page.goto('http://localhost:1234/mismatch-tag-with-class');69 return await page.screenshot({ fullPage: true });70 });71 await snapshot('match-child.png', async () => {72 await page.goto('http://localhost:1234/match-child');73 return await page.screenshot({ fullPage: true });74 });75 await snapshot('match-tag-in-text.png', async () => {76 await page.goto('http://localhost:1234/match-tag-in-text');77 return await page.screenshot({ fullPage: true });78 });79 await snapshot('match-nested-child.png', async () => {80 await page.goto('http://localhost:1234/match-nested-child');81 return await page.screenshot({ fullPage: true });82 });83 await snapshot('match-deeply-nested-child.png', async () => {84 await page.goto('http://localhost:1234/match-deeply-nested-child');85 return await page.screenshot({ fullPage: true });86 });87 await snapshot('match-sibling.png', async () => {88 await page.goto('http://localhost:1234/match-sibling');89 return await page.screenshot({ fullPage: true });90 });91 await snapshot('match-direct-child.png', async () => {92 await page.goto('http://localhost:1234/match-direct-child');93 return await page.screenshot({ fullPage: true });94 });95 await snapshot('match-adjacent.png', async () => {96 await page.goto('http://localhost:1234/match-adjacent');97 return await page.screenshot({ fullPage: true });98 });99 await snapshot('match-child-without-parent.png', async () => {100 await page.goto('http://localhost:1234/match-child-without-parent');101 return await page.screenshot({ fullPage: true });102 });103 await snapshot('match-first-child.png', async () => {104 await page.goto('http://localhost:1234/match-first-child');105 return await page.screenshot({ fullPage: true });106 });107 await browser.close();108};...
spa-routes.spec.js
Source:spa-routes.spec.js
1const { isSPA, checkText, baseURL, isMounted, wait } = require('../utils');2describe('SPA routes', () => {3 it('onHttpRequest: displayed', async () => {4 await page.goto(baseURL + '/spa');5 await isMounted();6 await checkText('#value', 'onHttpRequest');7 });8 it('onHttpRequest: error displayed', async () => {9 await page.goto(`${baseURL}/spa/on-http-request-error`);10 await wait(50);11 await isSPA();12 await checkText('h1', 'Error 500');13 });14 it('asyncData: data displayed', async () => {15 await page.goto(`${baseURL}/spa/async-data`);16 await wait(50);17 await isSPA();18 await isMounted();19 await checkText('#value', 'asyncData');20 });21 it('asyncData: state displayed', async () => {22 await page.goto(`${baseURL}/spa/async-data-store`);23 await wait(50);24 await isSPA();25 await isMounted();26 await checkText('#value', 'asyncDataStore');27 });28 it('asyncData: error displayed', async () => {29 await page.goto(`${baseURL}/spa/async-data-error`);30 await wait(50);31 await isSPA();32 await checkText('h1', 'Error 500');33 });34 it('redirect: called correctly', async () => {35 await page.goto(`${baseURL}/spa/redirect`);36 await wait(50);37 await isMounted();38 await checkText('h1', 'Home');39 });40 it('router: can display 404 error', async () => {41 await page.goto(`${baseURL}/spa/not-found`);42 await wait(50);43 await isSPA();44 await checkText('h1', 'Error 404');45 });46 it('middlewares: global state displayed', async () => {47 await page.goto(`${baseURL}/spa/global-middleware`);48 await wait(50);49 await isSPA();50 await isMounted();51 await checkText('#value', 'globalMiddleware');52 });53 it('middlewares: route state displayed', async () => {54 await page.goto(`${baseURL}/spa/route-middleware`);55 await wait(50);56 await isSPA();57 await isMounted();58 await checkText('#value', 'routeMiddleware');59 });60 it('middlewares: redirect', async () => {61 await page.goto(`${baseURL}/spa/middleware-redirect`);62 await wait(50);63 await isMounted();64 await checkText('h1', 'Home');65 });66 it('middlewares: error displayed', async () => {67 await page.goto(`${baseURL}/spa/middleware-error`);68 await wait(50);69 await isSPA();70 await checkText('h1', 'Error 500');71 });72 it('middlewares: error with helper displayed', async () => {73 await page.goto(`${baseURL}/spa/middleware-error-func`);74 await wait(50);75 await isSPA();76 await checkText('h1', 'Error 403');77 });78 it('asyncData: data on nested route displayed', async () => {79 await page.goto(`${baseURL}/spa/nested`);80 await wait(50);81 await isSPA();82 await isMounted();83 await checkText('#parent-value', 'parent');84 await checkText('#value', 'child');85 });86 it('middlewares: state on nested route displayed', async () => {87 await checkText('#parent', 'parent');88 await checkText('#middleware', 'child');89 });90 it('plugin: state is displayed', async () => {91 await page.goto(`${baseURL}/spa/plugin`);92 await wait(50);93 await isSPA();94 await isMounted();95 await checkText('#value', 'plugin');96 });...
Using AI Code Generation
1var sinon = require('sinon');2var assert = require('assert');3var puppeteer = require('puppeteer');4var browser = sinon.mock(puppeteer);5var page = sinon.mock(puppeteer.page);6var browserObject = browser.expects('launch').returns(Promise.resolve(browser));7var pageObject = page.expects('goto').returns(Promise.resolve(page));8var browserInstance = await browserObject.launch();9var pageInstance = await browserInstance.newPage();10assert(pageObject.calledOnce);11browser.restore();12page.restore();13browser.verify();14page.verify();15browser.restore();16page.restore();17browser.verify();18page.verify();
Using AI Code Generation
1const sinon = require('sinon');2const puppeteer = require('puppeteer');3const assert = require('assert');4describe('test', function () {5 let browser;6 let page;7 let sandbox;8 beforeEach(async function () {9 sandbox = sinon.createSandbox();10 browser = await puppeteer.launch({headless: false});11 page = await browser.newPage();12 });13 afterEach(function () {14 sandbox.restore();15 browser.close();16 });17 it('should open the page', async function () {18 const pageStub = sandbox.stub(page, 'goto');19 assert(pageStub.calledOnce);20 });21});22{23 "scripts": {24 },25 "dependencies": {26 }27}28{29 "dependencies": {30 "assert": {31 "requires": {32 }33 },34 "browser-process-hrtime": {
Using AI Code Generation
1const page = require('sinon-chrome/webextensions').tabs;2const browser = require('sinon-chrome/webextensions');3const browser = require('sinon-chrome/webextensions');4const browser = require('sinon-chrome/webextensions');5const browser = require('sinon-chrome/webextensions');6const browser = require('sinon-chrome/webextensions');7const browser = require('sinon-chrome/webextensions');8const browser = require('sinon-chrome/webextensions');9const browser = require('sinon-chrome/webextensions');10const browser = require('sinon-chrome/webextensions');11const browser = require('sinon-chrome/webextensions');12const browser = require('sinon-chrome/webextensions');13const browser = require('sinon-chrome/webextensions');14browser.tabs.query.yields({url
Using AI Code Generation
1const page = {2 goto: sinon.stub()3};4const page = {5 goto: sinon.stub()6};7const page = {8 goto: sinon.stub()9};10const page = {11 goto: sinon.stub()12};13const page = {14 goto: sinon.stub()15};16const page = {17 goto: sinon.stub()18};19const page = {20 goto: sinon.stub()21};22const page = {23 goto: sinon.stub()24};25const page = {26 goto: sinon.stub()27};28const page = {29 goto: sinon.stub()30};
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!