Best JavaScript code snippet using playwright-internal
network.spec.js
Source:network.spec.js
...127 await new Promise(x => serverResponse.end('ld!', x));128 expect(await responseText).toBe('hello world!');129 });130 it('Page.Events.RequestFailed', async({page, server}) => {131 await page.setRequestInterception(true);132 page.on('request', request => {133 if (request.url().endsWith('css'))134 request.abort();135 else136 request.continue();137 });138 const failedRequests = [];139 page.on('requestfailed', request => failedRequests.push(request));140 await page.goto(server.PREFIX + '/one-style.html');141 expect(failedRequests.length).toBe(1);142 expect(failedRequests[0].url()).toContain('one-style.css');143 expect(failedRequests[0].response()).toBe(null);144 expect(failedRequests[0].resourceType()).toBe('stylesheet');145 expect(failedRequests[0].failure().errorText).toBe('net::ERR_FAILED');146 expect(failedRequests[0].frame()).toBeTruthy();147 });148 it('Page.Events.RequestFinished', async({page, server}) => {149 const requests = [];150 page.on('requestfinished', request => requests.push(request));151 await page.goto(server.EMPTY_PAGE);152 expect(requests.length).toBe(1);153 expect(requests[0].url()).toBe(server.EMPTY_PAGE);154 expect(requests[0].response()).toBeTruthy();155 expect(requests[0].frame() === page.mainFrame()).toBe(true);156 expect(requests[0].frame().url()).toBe(server.EMPTY_PAGE);157 });158 it('should fire events in proper order', async({page, server}) => {159 const events = [];160 page.on('request', request => events.push('request'));161 page.on('response', response => events.push('response'));162 page.on('requestfinished', request => events.push('requestfinished'));163 await page.goto(server.EMPTY_PAGE);164 expect(events).toEqual(['request', 'response', 'requestfinished']);165 });166 it('should support redirects', async({page, server}) => {167 const events = [];168 page.on('request', request => events.push(`${request.method()} ${request.url()}`));169 page.on('response', response => events.push(`${response.status()} ${response.url()}`));170 page.on('requestfinished', request => events.push(`DONE ${request.url()}`));171 page.on('requestfailed', request => events.push(`FAIL ${request.url()}`));172 server.setRedirect('/foo.html', '/empty.html');173 const FOO_URL = server.PREFIX + '/foo.html';174 const response = await page.goto(FOO_URL);175 expect(events).toEqual([176 `GET ${FOO_URL}`,177 `302 ${FOO_URL}`,178 `DONE ${FOO_URL}`,179 `GET ${server.EMPTY_PAGE}`,180 `200 ${server.EMPTY_PAGE}`,181 `DONE ${server.EMPTY_PAGE}`182 ]);183 // Check redirect chain184 const redirectChain = response.request().redirectChain();185 expect(redirectChain.length).toBe(1);186 expect(redirectChain[0].url()).toContain('/foo.html');187 });188 });189 describe('Request.isNavigationRequest', () => {190 it('should work', async({page, server}) => {191 const requests = new Map();192 page.on('request', request => requests.set(request.url().split('/').pop(), request));193 server.setRedirect('/rrredirect', '/frames/one-frame.html');194 await page.goto(server.PREFIX + '/rrredirect');195 expect(requests.get('rrredirect').isNavigationRequest()).toBe(true);196 expect(requests.get('one-frame.html').isNavigationRequest()).toBe(true);197 expect(requests.get('frame.html').isNavigationRequest()).toBe(true);198 expect(requests.get('script.js').isNavigationRequest()).toBe(false);199 expect(requests.get('style.css').isNavigationRequest()).toBe(false);200 });201 it('should work with request interception', async({page, server}) => {202 const requests = new Map();203 page.on('request', request => {204 requests.set(request.url().split('/').pop(), request);205 request.continue();206 });207 await page.setRequestInterception(true);208 server.setRedirect('/rrredirect', '/frames/one-frame.html');209 await page.goto(server.PREFIX + '/rrredirect');210 expect(requests.get('rrredirect').isNavigationRequest()).toBe(true);211 expect(requests.get('one-frame.html').isNavigationRequest()).toBe(true);212 expect(requests.get('frame.html').isNavigationRequest()).toBe(true);213 expect(requests.get('script.js').isNavigationRequest()).toBe(false);214 expect(requests.get('style.css').isNavigationRequest()).toBe(false);215 });216 it('should work when navigating to image', async({page, server}) => {217 const requests = [];218 page.on('request', request => requests.push(request));219 await page.goto(server.PREFIX + '/pptr.png');220 expect(requests[0].isNavigationRequest()).toBe(true);221 });222 });223 describe('Page.setRequestInterception', function() {224 it('should intercept', async({page, server}) => {225 await page.setRequestInterception(true);226 page.on('request', request => {227 expect(request.url()).toContain('empty.html');228 expect(request.headers()['user-agent']).toBeTruthy();229 expect(request.method()).toBe('GET');230 expect(request.postData()).toBe(undefined);231 expect(request.isNavigationRequest()).toBe(true);232 expect(request.resourceType()).toBe('document');233 expect(request.frame() === page.mainFrame()).toBe(true);234 expect(request.frame().url()).toBe('about:blank');235 request.continue();236 });237 const response = await page.goto(server.EMPTY_PAGE);238 expect(response.ok()).toBe(true);239 });240 it('should contain referer header', async({page, server}) => {241 await page.setRequestInterception(true);242 const requests = [];243 page.on('request', request => {244 requests.push(request);245 request.continue();246 });247 await page.goto(server.PREFIX + '/one-style.html');248 expect(requests[1].url()).toContain('/one-style.css');249 expect(requests[1].headers().referer).toContain('/one-style.html');250 });251 it('should properly return navigation response when URL has cookies', async({page, server}) => {252 // Setup cookie.253 await page.goto(server.EMPTY_PAGE);254 await page.setCookie({ name: 'foo', value: 'bar'});255 // Setup request interception.256 await page.setRequestInterception(true);257 page.on('request', request => request.continue());258 const response = await page.reload();259 expect(response.status()).toBe(200);260 });261 it('should stop intercepting', async({page, server}) => {262 await page.setRequestInterception(true);263 page.once('request', request => request.continue());264 await page.goto(server.EMPTY_PAGE);265 await page.setRequestInterception(false);266 await page.goto(server.EMPTY_PAGE);267 });268 it('should show custom HTTP headers', async({page, server}) => {269 await page.setExtraHTTPHeaders({270 foo: 'bar'271 });272 await page.setRequestInterception(true);273 page.on('request', request => {274 expect(request.headers()['foo']).toBe('bar');275 request.continue();276 });277 const response = await page.goto(server.EMPTY_PAGE);278 expect(response.ok()).toBe(true);279 });280 it('should works with customizing referer headers', async({page, server}) => {281 await page.setExtraHTTPHeaders({ 'referer': server.EMPTY_PAGE });282 await page.setRequestInterception(true);283 page.on('request', request => {284 expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);285 request.continue();286 });287 const response = await page.goto(server.EMPTY_PAGE);288 expect(response.ok()).toBe(true);289 });290 it('should be abortable', async({page, server}) => {291 await page.setRequestInterception(true);292 page.on('request', request => {293 if (request.url().endsWith('.css'))294 request.abort();295 else296 request.continue();297 });298 let failedRequests = 0;299 page.on('requestfailed', event => ++failedRequests);300 const response = await page.goto(server.PREFIX + '/one-style.html');301 expect(response.ok()).toBe(true);302 expect(response.request().failure()).toBe(null);303 expect(failedRequests).toBe(1);304 });305 it('should be abortable with custom error codes', async({page, server}) => {306 await page.setRequestInterception(true);307 page.on('request', request => {308 request.abort('internetdisconnected');309 });310 let failedRequest = null;311 page.on('requestfailed', request => failedRequest = request);312 await page.goto(server.EMPTY_PAGE).catch(e => {});313 expect(failedRequest).toBeTruthy();314 expect(failedRequest.failure().errorText).toBe('net::ERR_INTERNET_DISCONNECTED');315 });316 it('should send referer', async({page, server}) => {317 await page.setExtraHTTPHeaders({318 referer: 'http://google.com/'319 });320 await page.setRequestInterception(true);321 page.on('request', request => request.continue());322 const [request] = await Promise.all([323 server.waitForRequest('/grid.html'),324 page.goto(server.PREFIX + '/grid.html'),325 ]);326 expect(request.headers['referer']).toBe('http://google.com/');327 });328 it('should amend HTTP headers', async({page, server}) => {329 await page.setRequestInterception(true);330 page.on('request', request => {331 const headers = Object.assign({}, request.headers());332 headers['FOO'] = 'bar';333 request.continue({ headers });334 });335 await page.goto(server.EMPTY_PAGE);336 const [request] = await Promise.all([337 server.waitForRequest('/sleep.zzz'),338 page.evaluate(() => fetch('/sleep.zzz'))339 ]);340 expect(request.headers['foo']).toBe('bar');341 });342 it('should fail navigation when aborting main resource', async({page, server}) => {343 await page.setRequestInterception(true);344 page.on('request', request => request.abort());345 let error = null;346 await page.goto(server.EMPTY_PAGE).catch(e => error = e);347 expect(error).toBeTruthy();348 expect(error.message).toContain('net::ERR_FAILED');349 });350 it('should work with redirects', async({page, server}) => {351 await page.setRequestInterception(true);352 const requests = [];353 page.on('request', request => {354 request.continue();355 requests.push(request);356 });357 server.setRedirect('/non-existing-page.html', '/non-existing-page-2.html');358 server.setRedirect('/non-existing-page-2.html', '/non-existing-page-3.html');359 server.setRedirect('/non-existing-page-3.html', '/non-existing-page-4.html');360 server.setRedirect('/non-existing-page-4.html', '/empty.html');361 const response = await page.goto(server.PREFIX + '/non-existing-page.html');362 expect(response.status()).toBe(200);363 expect(response.url()).toContain('empty.html');364 expect(requests.length).toBe(5);365 expect(requests[2].resourceType()).toBe('document');366 // Check redirect chain367 const redirectChain = response.request().redirectChain();368 expect(redirectChain.length).toBe(4);369 expect(redirectChain[0].url()).toContain('/non-existing-page.html');370 expect(redirectChain[2].url()).toContain('/non-existing-page-3.html');371 for (let i = 0; i < redirectChain.length; ++i) {372 const request = redirectChain[i];373 expect(request.isNavigationRequest()).toBe(true);374 expect(request.redirectChain().indexOf(request)).toBe(i);375 }376 });377 it('should work with redirects for subresources', async({page, server}) => {378 await page.setRequestInterception(true);379 const requests = [];380 page.on('request', request => {381 request.continue();382 requests.push(request);383 });384 server.setRedirect('/one-style.css', '/two-style.css');385 server.setRedirect('/two-style.css', '/three-style.css');386 server.setRedirect('/three-style.css', '/four-style.css');387 server.setRoute('/four-style.css', (req, res) => res.end('body {box-sizing: border-box; }'));388 const response = await page.goto(server.PREFIX + '/one-style.html');389 expect(response.status()).toBe(200);390 expect(response.url()).toContain('one-style.html');391 expect(requests.length).toBe(5);392 expect(requests[0].resourceType()).toBe('document');393 expect(requests[1].resourceType()).toBe('stylesheet');394 // Check redirect chain395 const redirectChain = requests[1].redirectChain();396 expect(redirectChain.length).toBe(3);397 expect(redirectChain[0].url()).toContain('/one-style.css');398 expect(redirectChain[2].url()).toContain('/three-style.css');399 });400 it('should be able to abort redirects', async({page, server}) => {401 await page.setRequestInterception(true);402 server.setRedirect('/non-existing.json', '/non-existing-2.json');403 server.setRedirect('/non-existing-2.json', '/simple.html');404 page.on('request', request => {405 if (request.url().includes('non-existing-2'))406 request.abort();407 else408 request.continue();409 });410 await page.goto(server.EMPTY_PAGE);411 const result = await page.evaluate(async() => {412 try {413 await fetch('/non-existing.json');414 } catch (e) {415 return e.message;416 }417 });418 expect(result).toContain('Failed to fetch');419 });420 it('should work with equal requests', async({page, server}) => {421 await page.goto(server.EMPTY_PAGE);422 let responseCount = 1;423 server.setRoute('/zzz', (req, res) => res.end((responseCount++) * 11 + ''));424 await page.setRequestInterception(true);425 let spinner = false;426 // Cancel 2nd request.427 page.on('request', request => {428 spinner ? request.abort() : request.continue();429 spinner = !spinner;430 });431 const results = await page.evaluate(() => Promise.all([432 fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),433 fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),434 fetch('/zzz').then(response => response.text()).catch(e => 'FAILED'),435 ]));436 expect(results).toEqual(['11', 'FAILED', '22']);437 });438 it('should navigate to dataURL and fire dataURL requests', async({page, server}) => {439 await page.setRequestInterception(true);440 const requests = [];441 page.on('request', request => {442 requests.push(request);443 request.continue();444 });445 const dataURL = 'data:text/html,<div>yo</div>';446 const response = await page.goto(dataURL);447 expect(response.status()).toBe(200);448 expect(requests.length).toBe(1);449 expect(requests[0].url()).toBe(dataURL);450 });451 it('should abort data server', async({page, server}) => {452 await page.setRequestInterception(true);453 page.on('request', request => {454 request.abort();455 });456 let error = null;457 await page.goto('data:text/html,No way!').catch(err => error = err);458 expect(error.message).toContain('net::ERR_FAILED');459 });460 it('should navigate to URL with hash and and fire requests without hash', async({page, server}) => {461 await page.setRequestInterception(true);462 const requests = [];463 page.on('request', request => {464 requests.push(request);465 request.continue();466 });467 const response = await page.goto(server.EMPTY_PAGE + '#hash');468 expect(response.status()).toBe(200);469 expect(response.url()).toBe(server.EMPTY_PAGE);470 expect(requests.length).toBe(1);471 expect(requests[0].url()).toBe(server.EMPTY_PAGE);472 });473 it('should work with encoded server', async({page, server}) => {474 // The requestWillBeSent will report encoded URL, whereas interception will475 // report URL as-is. @see crbug.com/759388476 await page.setRequestInterception(true);477 page.on('request', request => request.continue());478 const response = await page.goto(server.PREFIX + '/some nonexisting page');479 expect(response.status()).toBe(404);480 });481 it('should work with badly encoded server', async({page, server}) => {482 await page.setRequestInterception(true);483 server.setRoute('/malformed?rnd=%911', (req, res) => res.end());484 page.on('request', request => request.continue());485 const response = await page.goto(server.PREFIX + '/malformed?rnd=%911');486 expect(response.status()).toBe(200);487 });488 it('should work with encoded server - 2', async({page, server}) => {489 // The requestWillBeSent will report URL as-is, whereas interception will490 // report encoded URL for stylesheet. @see crbug.com/759388491 await page.setRequestInterception(true);492 const requests = [];493 page.on('request', request => {494 request.continue();495 requests.push(request);496 });497 const response = await page.goto(`data:text/html,<link rel="stylesheet" href="${server.PREFIX}/fonts?helvetica|arial"/>`);498 expect(response.status()).toBe(200);499 expect(requests.length).toBe(2);500 expect(requests[1].response().status()).toBe(404);501 });502 it('should not throw "Invalid Interception Id" if the request was cancelled', async({page, server}) => {503 await page.setContent('<iframe></iframe>');504 await page.setRequestInterception(true);505 let request = null;506 page.on('request', async r => request = r);507 page.$eval('iframe', (frame, url) => frame.src = url, server.EMPTY_PAGE),508 // Wait for request interception.509 await utils.waitEvent(page, 'request');510 // Delete frame to cause request to be canceled.511 await page.$eval('iframe', frame => frame.remove());512 let error = null;513 await request.continue().catch(e => error = e);514 expect(error).toBe(null);515 });516 it('should throw if interception is not enabled', async({page, server}) => {517 let error = null;518 page.on('request', async request => {519 try {520 await request.continue();521 } catch (e) {522 error = e;523 }524 });525 await page.goto(server.EMPTY_PAGE);526 expect(error.message).toContain('Request Interception is not enabled');527 });528 it('should work with file URLs', async({page, server}) => {529 await page.setRequestInterception(true);530 const urls = new Set();531 page.on('request', request => {532 urls.add(request.url().split('/').pop());533 request.continue();534 });535 await page.goto(pathToFileURL(path.join(__dirname, 'assets', 'one-style.html')));536 expect(urls.size).toBe(2);537 expect(urls.has('one-style.html')).toBe(true);538 expect(urls.has('one-style.css')).toBe(true);539 });540 });541 describe('Request.respond', function() {542 it('should work', async({page, server}) => {543 await page.setRequestInterception(true);544 page.on('request', request => {545 request.respond({546 status: 201,547 headers: {548 foo: 'bar'549 },550 body: 'Yo, page!'551 });552 });553 const response = await page.goto(server.EMPTY_PAGE);554 expect(response.status()).toBe(201);555 expect(response.headers().foo).toBe('bar');556 expect(await page.evaluate(() => document.body.textContent)).toBe('Yo, page!');557 });558 it('should allow mocking binary responses', async({page, server}) => {559 await page.setRequestInterception(true);560 page.on('request', request => {561 const imageBuffer = fs.readFileSync(path.join(__dirname, 'assets', 'pptr.png'));562 request.respond({563 contentType: 'image/png',564 body: imageBuffer565 });566 });567 await page.evaluate(PREFIX => {568 const img = document.createElement('img');569 img.src = PREFIX + '/does-not-exist.png';570 document.body.appendChild(img);571 return new Promise(fulfill => img.onload = fulfill);572 }, server.PREFIX);573 const img = await page.$('img');...
requestinterception.spec.js
Source:requestinterception.spec.js
...27 setupTestPageAndContextHooks();28 describeFailsFirefox('Page.setRequestInterception', function () {29 it('should intercept', async () => {30 const { page, server } = getTestState();31 await page.setRequestInterception(true);32 page.on('request', (request) => {33 if (utils.isFavicon(request)) {34 request.continue();35 return;36 }37 expect(request.url()).toContain('empty.html');38 expect(request.headers()['user-agent']).toBeTruthy();39 expect(request.method()).toBe('GET');40 expect(request.postData()).toBe(undefined);41 expect(request.isNavigationRequest()).toBe(true);42 expect(request.resourceType()).toBe('document');43 expect(request.frame() === page.mainFrame()).toBe(true);44 expect(request.frame().url()).toBe('about:blank');45 request.continue();46 });47 const response = await page.goto(server.EMPTY_PAGE);48 expect(response.ok()).toBe(true);49 expect(response.remoteAddress().port).toBe(server.PORT);50 });51 it('should work when POST is redirected with 302', async () => {52 const { page, server } = getTestState();53 server.setRedirect('/rredirect', '/empty.html');54 await page.goto(server.EMPTY_PAGE);55 await page.setRequestInterception(true);56 page.on('request', (request) => request.continue());57 await page.setContent(`58 <form action='/rredirect' method='post'>59 <input type="hidden" id="foo" name="foo" value="FOOBAR">60 </form>61 `);62 await Promise.all([63 page.$eval('form', (form) => form.submit()),64 page.waitForNavigation(),65 ]);66 });67 // @see https://github.com/puppeteer/puppeteer/issues/397368 it('should work when header manipulation headers with redirect', async () => {69 const { page, server } = getTestState();70 server.setRedirect('/rrredirect', '/empty.html');71 await page.setRequestInterception(true);72 page.on('request', (request) => {73 const headers = Object.assign({}, request.headers(), {74 foo: 'bar',75 });76 request.continue({ headers });77 });78 await page.goto(server.PREFIX + '/rrredirect');79 });80 // @see https://github.com/puppeteer/puppeteer/issues/474381 it('should be able to remove headers', async () => {82 const { page, server } = getTestState();83 await page.setRequestInterception(true);84 page.on('request', (request) => {85 const headers = Object.assign({}, request.headers(), {86 foo: 'bar',87 origin: undefined, // remove "origin" header88 });89 request.continue({ headers });90 });91 const [serverRequest] = await Promise.all([92 server.waitForRequest('/empty.html'),93 page.goto(server.PREFIX + '/empty.html'),94 ]);95 expect(serverRequest.headers.origin).toBe(undefined);96 });97 it('should contain referer header', async () => {98 const { page, server } = getTestState();99 await page.setRequestInterception(true);100 const requests = [];101 page.on('request', (request) => {102 if (!utils.isFavicon(request)) requests.push(request);103 request.continue();104 });105 await page.goto(server.PREFIX + '/one-style.html');106 expect(requests[1].url()).toContain('/one-style.css');107 expect(requests[1].headers().referer).toContain('/one-style.html');108 });109 it('should properly return navigation response when URL has cookies', async () => {110 const { page, server } = getTestState();111 // Setup cookie.112 await page.goto(server.EMPTY_PAGE);113 await page.setCookie({ name: 'foo', value: 'bar' });114 // Setup request interception.115 await page.setRequestInterception(true);116 page.on('request', (request) => request.continue());117 const response = await page.reload();118 expect(response.status()).toBe(200);119 });120 it('should stop intercepting', async () => {121 const { page, server } = getTestState();122 await page.setRequestInterception(true);123 page.once('request', (request) => request.continue());124 await page.goto(server.EMPTY_PAGE);125 await page.setRequestInterception(false);126 await page.goto(server.EMPTY_PAGE);127 });128 it('should show custom HTTP headers', async () => {129 const { page, server } = getTestState();130 await page.setExtraHTTPHeaders({131 foo: 'bar',132 });133 await page.setRequestInterception(true);134 page.on('request', (request) => {135 expect(request.headers()['foo']).toBe('bar');136 request.continue();137 });138 const response = await page.goto(server.EMPTY_PAGE);139 expect(response.ok()).toBe(true);140 });141 // @see https://github.com/puppeteer/puppeteer/issues/4337142 it('should work with redirect inside sync XHR', async () => {143 const { page, server } = getTestState();144 await page.goto(server.EMPTY_PAGE);145 server.setRedirect('/logo.png', '/pptr.png');146 await page.setRequestInterception(true);147 page.on('request', (request) => request.continue());148 const status = await page.evaluate(async () => {149 const request = new XMLHttpRequest();150 request.open('GET', '/logo.png', false); // `false` makes the request synchronous151 request.send(null);152 return request.status;153 });154 expect(status).toBe(200);155 });156 it('should work with custom referer headers', async () => {157 const { page, server } = getTestState();158 await page.setExtraHTTPHeaders({ referer: server.EMPTY_PAGE });159 await page.setRequestInterception(true);160 page.on('request', (request) => {161 expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);162 request.continue();163 });164 const response = await page.goto(server.EMPTY_PAGE);165 expect(response.ok()).toBe(true);166 });167 it('should be abortable', async () => {168 const { page, server } = getTestState();169 await page.setRequestInterception(true);170 page.on('request', (request) => {171 if (request.url().endsWith('.css')) request.abort();172 else request.continue();173 });174 let failedRequests = 0;175 page.on('requestfailed', (event) => ++failedRequests);176 const response = await page.goto(server.PREFIX + '/one-style.html');177 expect(response.ok()).toBe(true);178 expect(response.request().failure()).toBe(null);179 expect(failedRequests).toBe(1);180 });181 it('should be abortable with custom error codes', async () => {182 const { page, server } = getTestState();183 await page.setRequestInterception(true);184 page.on('request', (request) => {185 request.abort('internetdisconnected');186 });187 let failedRequest = null;188 page.on('requestfailed', (request) => (failedRequest = request));189 await page.goto(server.EMPTY_PAGE).catch((error) => {});190 expect(failedRequest).toBeTruthy();191 expect(failedRequest.failure().errorText).toBe(192 'net::ERR_INTERNET_DISCONNECTED'193 );194 });195 it('should send referer', async () => {196 const { page, server } = getTestState();197 await page.setExtraHTTPHeaders({198 referer: 'http://google.com/',199 });200 await page.setRequestInterception(true);201 page.on('request', (request) => request.continue());202 const [request] = await Promise.all([203 server.waitForRequest('/grid.html'),204 page.goto(server.PREFIX + '/grid.html'),205 ]);206 expect(request.headers['referer']).toBe('http://google.com/');207 });208 it('should fail navigation when aborting main resource', async () => {209 const { page, server, isChrome } = getTestState();210 await page.setRequestInterception(true);211 page.on('request', (request) => request.abort());212 let error = null;213 await page.goto(server.EMPTY_PAGE).catch((error_) => (error = error_));214 expect(error).toBeTruthy();215 if (isChrome) expect(error.message).toContain('net::ERR_FAILED');216 else expect(error.message).toContain('NS_ERROR_FAILURE');217 });218 it('should work with redirects', async () => {219 const { page, server } = getTestState();220 await page.setRequestInterception(true);221 const requests = [];222 page.on('request', (request) => {223 request.continue();224 requests.push(request);225 });226 server.setRedirect(227 '/non-existing-page.html',228 '/non-existing-page-2.html'229 );230 server.setRedirect(231 '/non-existing-page-2.html',232 '/non-existing-page-3.html'233 );234 server.setRedirect(235 '/non-existing-page-3.html',236 '/non-existing-page-4.html'237 );238 server.setRedirect('/non-existing-page-4.html', '/empty.html');239 const response = await page.goto(240 server.PREFIX + '/non-existing-page.html'241 );242 expect(response.status()).toBe(200);243 expect(response.url()).toContain('empty.html');244 expect(requests.length).toBe(5);245 expect(requests[2].resourceType()).toBe('document');246 // Check redirect chain247 const redirectChain = response.request().redirectChain();248 expect(redirectChain.length).toBe(4);249 expect(redirectChain[0].url()).toContain('/non-existing-page.html');250 expect(redirectChain[2].url()).toContain('/non-existing-page-3.html');251 for (let i = 0; i < redirectChain.length; ++i) {252 const request = redirectChain[i];253 expect(request.isNavigationRequest()).toBe(true);254 expect(request.redirectChain().indexOf(request)).toBe(i);255 }256 });257 it('should work with redirects for subresources', async () => {258 const { page, server } = getTestState();259 await page.setRequestInterception(true);260 const requests = [];261 page.on('request', (request) => {262 request.continue();263 if (!utils.isFavicon(request)) requests.push(request);264 });265 server.setRedirect('/one-style.css', '/two-style.css');266 server.setRedirect('/two-style.css', '/three-style.css');267 server.setRedirect('/three-style.css', '/four-style.css');268 server.setRoute('/four-style.css', (req, res) =>269 res.end('body {box-sizing: border-box; }')270 );271 const response = await page.goto(server.PREFIX + '/one-style.html');272 expect(response.status()).toBe(200);273 expect(response.url()).toContain('one-style.html');274 expect(requests.length).toBe(5);275 expect(requests[0].resourceType()).toBe('document');276 expect(requests[1].resourceType()).toBe('stylesheet');277 // Check redirect chain278 const redirectChain = requests[1].redirectChain();279 expect(redirectChain.length).toBe(3);280 expect(redirectChain[0].url()).toContain('/one-style.css');281 expect(redirectChain[2].url()).toContain('/three-style.css');282 });283 it('should be able to abort redirects', async () => {284 const { page, server, isChrome } = getTestState();285 await page.setRequestInterception(true);286 server.setRedirect('/non-existing.json', '/non-existing-2.json');287 server.setRedirect('/non-existing-2.json', '/simple.html');288 page.on('request', (request) => {289 if (request.url().includes('non-existing-2')) request.abort();290 else request.continue();291 });292 await page.goto(server.EMPTY_PAGE);293 const result = await page.evaluate(async () => {294 try {295 await fetch('/non-existing.json');296 } catch (error) {297 return error.message;298 }299 });300 if (isChrome) expect(result).toContain('Failed to fetch');301 else expect(result).toContain('NetworkError');302 });303 it('should work with equal requests', async () => {304 const { page, server } = getTestState();305 await page.goto(server.EMPTY_PAGE);306 let responseCount = 1;307 server.setRoute('/zzz', (req, res) => res.end(responseCount++ * 11 + ''));308 await page.setRequestInterception(true);309 let spinner = false;310 // Cancel 2nd request.311 page.on('request', (request) => {312 if (utils.isFavicon(request)) {313 request.continue();314 return;315 }316 spinner ? request.abort() : request.continue();317 spinner = !spinner;318 });319 const results = await page.evaluate(() =>320 Promise.all([321 fetch('/zzz')322 .then((response) => response.text())323 .catch((error) => 'FAILED'),324 fetch('/zzz')325 .then((response) => response.text())326 .catch((error) => 'FAILED'),327 fetch('/zzz')328 .then((response) => response.text())329 .catch((error) => 'FAILED'),330 ])331 );332 expect(results).toEqual(['11', 'FAILED', '22']);333 });334 it('should navigate to dataURL and fire dataURL requests', async () => {335 const { page } = getTestState();336 await page.setRequestInterception(true);337 const requests = [];338 page.on('request', (request) => {339 requests.push(request);340 request.continue();341 });342 const dataURL = 'data:text/html,<div>yo</div>';343 const response = await page.goto(dataURL);344 expect(response.status()).toBe(200);345 expect(requests.length).toBe(1);346 expect(requests[0].url()).toBe(dataURL);347 });348 it('should be able to fetch dataURL and fire dataURL requests', async () => {349 const { page, server } = getTestState();350 await page.goto(server.EMPTY_PAGE);351 await page.setRequestInterception(true);352 const requests = [];353 page.on('request', (request) => {354 requests.push(request);355 request.continue();356 });357 const dataURL = 'data:text/html,<div>yo</div>';358 const text = await page.evaluate(359 (url) => fetch(url).then((r) => r.text()),360 dataURL361 );362 expect(text).toBe('<div>yo</div>');363 expect(requests.length).toBe(1);364 expect(requests[0].url()).toBe(dataURL);365 });366 it('should navigate to URL with hash and and fire requests without hash', async () => {367 const { page, server } = getTestState();368 await page.setRequestInterception(true);369 const requests = [];370 page.on('request', (request) => {371 requests.push(request);372 request.continue();373 });374 const response = await page.goto(server.EMPTY_PAGE + '#hash');375 expect(response.status()).toBe(200);376 expect(response.url()).toBe(server.EMPTY_PAGE);377 expect(requests.length).toBe(1);378 expect(requests[0].url()).toBe(server.EMPTY_PAGE);379 });380 it('should work with encoded server', async () => {381 const { page, server } = getTestState();382 // The requestWillBeSent will report encoded URL, whereas interception will383 // report URL as-is. @see crbug.com/759388384 await page.setRequestInterception(true);385 page.on('request', (request) => request.continue());386 const response = await page.goto(387 server.PREFIX + '/some nonexisting page'388 );389 expect(response.status()).toBe(404);390 });391 it('should work with badly encoded server', async () => {392 const { page, server } = getTestState();393 await page.setRequestInterception(true);394 server.setRoute('/malformed?rnd=%911', (req, res) => res.end());395 page.on('request', (request) => request.continue());396 const response = await page.goto(server.PREFIX + '/malformed?rnd=%911');397 expect(response.status()).toBe(200);398 });399 it('should work with encoded server - 2', async () => {400 const { page, server } = getTestState();401 // The requestWillBeSent will report URL as-is, whereas interception will402 // report encoded URL for stylesheet. @see crbug.com/759388403 await page.setRequestInterception(true);404 const requests = [];405 page.on('request', (request) => {406 request.continue();407 requests.push(request);408 });409 const response = await page.goto(410 `data:text/html,<link rel="stylesheet" href="${server.PREFIX}/fonts?helvetica|arial"/>`411 );412 expect(response.status()).toBe(200);413 expect(requests.length).toBe(2);414 expect(requests[1].response().status()).toBe(404);415 });416 it('should not throw "Invalid Interception Id" if the request was cancelled', async () => {417 const { page, server } = getTestState();418 await page.setContent('<iframe></iframe>');419 await page.setRequestInterception(true);420 let request = null;421 page.on('request', async (r) => (request = r));422 page.$eval(423 'iframe',424 (frame, url) => (frame.src = url),425 server.EMPTY_PAGE426 ),427 // Wait for request interception.428 await utils.waitEvent(page, 'request');429 // Delete frame to cause request to be canceled.430 await page.$eval('iframe', (frame) => frame.remove());431 let error = null;432 await request.continue().catch((error_) => (error = error_));433 expect(error).toBe(null);434 });435 it('should throw if interception is not enabled', async () => {436 const { page, server } = getTestState();437 let error = null;438 page.on('request', async (request) => {439 try {440 await request.continue();441 } catch (error_) {442 error = error_;443 }444 });445 await page.goto(server.EMPTY_PAGE);446 expect(error.message).toContain('Request Interception is not enabled');447 });448 it('should work with file URLs', async () => {449 const { page } = getTestState();450 await page.setRequestInterception(true);451 const urls = new Set();452 page.on('request', (request) => {453 urls.add(request.url().split('/').pop());454 request.continue();455 });456 await page.goto(457 pathToFileURL(path.join(__dirname, 'assets', 'one-style.html'))458 );459 expect(urls.size).toBe(2);460 expect(urls.has('one-style.html')).toBe(true);461 expect(urls.has('one-style.css')).toBe(true);462 });463 });464 describeFailsFirefox('Request.continue', function () {465 it('should work', async () => {466 const { page, server } = getTestState();467 await page.setRequestInterception(true);468 page.on('request', (request) => request.continue());469 await page.goto(server.EMPTY_PAGE);470 });471 it('should amend HTTP headers', async () => {472 const { page, server } = getTestState();473 await page.setRequestInterception(true);474 page.on('request', (request) => {475 const headers = Object.assign({}, request.headers());476 headers['FOO'] = 'bar';477 request.continue({ headers });478 });479 await page.goto(server.EMPTY_PAGE);480 const [request] = await Promise.all([481 server.waitForRequest('/sleep.zzz'),482 page.evaluate(() => fetch('/sleep.zzz')),483 ]);484 expect(request.headers['foo']).toBe('bar');485 });486 it('should redirect in a way non-observable to page', async () => {487 const { page, server } = getTestState();488 await page.setRequestInterception(true);489 page.on('request', (request) => {490 const redirectURL = request.url().includes('/empty.html')491 ? server.PREFIX + '/consolelog.html'492 : undefined;493 request.continue({ url: redirectURL });494 });495 let consoleMessage = null;496 page.on('console', (msg) => (consoleMessage = msg));497 await page.goto(server.EMPTY_PAGE);498 expect(page.url()).toBe(server.EMPTY_PAGE);499 expect(consoleMessage.text()).toBe('yellow');500 });501 it('should amend method', async () => {502 const { page, server } = getTestState();503 await page.goto(server.EMPTY_PAGE);504 await page.setRequestInterception(true);505 page.on('request', (request) => {506 request.continue({ method: 'POST' });507 });508 const [request] = await Promise.all([509 server.waitForRequest('/sleep.zzz'),510 page.evaluate(() => fetch('/sleep.zzz')),511 ]);512 expect(request.method).toBe('POST');513 });514 it('should amend post data', async () => {515 const { page, server } = getTestState();516 await page.goto(server.EMPTY_PAGE);517 await page.setRequestInterception(true);518 page.on('request', (request) => {519 request.continue({ postData: 'doggo' });520 });521 const [serverRequest] = await Promise.all([522 server.waitForRequest('/sleep.zzz'),523 page.evaluate(() =>524 fetch('/sleep.zzz', { method: 'POST', body: 'birdy' })525 ),526 ]);527 expect(await serverRequest.postBody).toBe('doggo');528 });529 it('should amend both post data and method on navigation', async () => {530 const { page, server } = getTestState();531 await page.setRequestInterception(true);532 page.on('request', (request) => {533 request.continue({ method: 'POST', postData: 'doggo' });534 });535 const [serverRequest] = await Promise.all([536 server.waitForRequest('/empty.html'),537 page.goto(server.EMPTY_PAGE),538 ]);539 expect(serverRequest.method).toBe('POST');540 expect(await serverRequest.postBody).toBe('doggo');541 });542 });543 describeFailsFirefox('Request.respond', function () {544 it('should work', async () => {545 const { page, server } = getTestState();546 await page.setRequestInterception(true);547 page.on('request', (request) => {548 request.respond({549 status: 201,550 headers: {551 foo: 'bar',552 },553 body: 'Yo, page!',554 });555 });556 const response = await page.goto(server.EMPTY_PAGE);557 expect(response.status()).toBe(201);558 expect(response.headers().foo).toBe('bar');559 expect(await page.evaluate(() => document.body.textContent)).toBe(560 'Yo, page!'561 );562 });563 it('should work with status code 422', async () => {564 const { page, server } = getTestState();565 await page.setRequestInterception(true);566 page.on('request', (request) => {567 request.respond({568 status: 422,569 body: 'Yo, page!',570 });571 });572 const response = await page.goto(server.EMPTY_PAGE);573 expect(response.status()).toBe(422);574 expect(response.statusText()).toBe('Unprocessable Entity');575 expect(await page.evaluate(() => document.body.textContent)).toBe(576 'Yo, page!'577 );578 });579 it('should redirect', async () => {580 const { page, server } = getTestState();581 await page.setRequestInterception(true);582 page.on('request', (request) => {583 if (!request.url().includes('rrredirect')) {584 request.continue();585 return;586 }587 request.respond({588 status: 302,589 headers: {590 location: server.EMPTY_PAGE,591 },592 });593 });594 const response = await page.goto(server.PREFIX + '/rrredirect');595 expect(response.request().redirectChain().length).toBe(1);596 expect(response.request().redirectChain()[0].url()).toBe(597 server.PREFIX + '/rrredirect'598 );599 expect(response.url()).toBe(server.EMPTY_PAGE);600 });601 it('should allow mocking binary responses', async () => {602 const { page, server } = getTestState();603 await page.setRequestInterception(true);604 page.on('request', (request) => {605 const imageBuffer = fs.readFileSync(606 path.join(__dirname, 'assets', 'pptr.png')607 );608 request.respond({609 contentType: 'image/png',610 body: imageBuffer,611 });612 });613 await page.evaluate((PREFIX) => {614 const img = document.createElement('img');615 img.src = PREFIX + '/does-not-exist.png';616 document.body.appendChild(img);617 return new Promise((fulfill) => (img.onload = fulfill));618 }, server.PREFIX);619 const img = await page.$('img');620 expect(await img.screenshot()).toBeGolden('mock-binary-response.png');621 });622 it('should stringify intercepted request response headers', async () => {623 const { page, server } = getTestState();624 await page.setRequestInterception(true);625 page.on('request', (request) => {626 request.respond({627 status: 200,628 headers: {629 foo: true,630 },631 body: 'Yo, page!',632 });633 });634 const response = await page.goto(server.EMPTY_PAGE);635 expect(response.status()).toBe(200);636 const headers = response.headers();637 expect(headers.foo).toBe('true');638 expect(await page.evaluate(() => document.body.textContent)).toBe(...
requestinterception.js
Source:requestinterception.js
...27 await helper.end()28})29test.serial('Page.setRequestInterception should intercept', async t => {30 const { page, server } = t.context31 await page.setRequestInterception(true)32 page.on('request', request => {33 if (utils.isFavicon(request)) {34 request.continue()35 return36 }37 t.true(request.url().includes('empty.html'))38 t.truthy(request.normalizedHeaders()['user-agent'])39 t.is(request.method(), 'GET')40 t.falsy(request.postData())41 t.true(request.isNavigationRequest())42 t.is(request.resourceType(), 'document')43 t.true(request.frame() === page.mainFrame())44 t.is(request.frame().url(), 'about:blank')45 request.continue()46 })47 const response = await page.goto(server.EMPTY_PAGE)48 t.true(response.ok())49 t.is(response.remoteAddress().port, server.PORT)50})51test.serial(52 'Page.setRequestInterception should work when POST is redirected with 302',53 async t => {54 const { page, server } = t.context55 await page.goto(server.EMPTY_PAGE)56 await page.setRequestInterception(true)57 page.on('request', request => request.continue())58 await page.setContent(`59 <form action='/rredirect' method='post'>60 <input type="hidden" id="foo" name="foo" value="FOOBAR">61 </form>62 `)63 await Promise.all([64 page.$eval('form', form => form.submit()),65 page.waitForNavigation()66 ])67 t.pass()68 }69)70test.serial.skip(71 'Page.setRequestInterception should work when header manipulation headers with redirect',72 async t => {73 const { page, server } = t.context74 page.on('request', request => {75 if (!request.url().endsWith('/redirectToEmpty')) return76 const headers = Object.assign({}, request.headers(), {77 foo: 'bar'78 })79 request.continue({80 headers81 })82 })83 await page.goto(server.PREFIX + '/interceptMe.html')84 await page.setRequestInterception(true)85 const results = await page.evaluate(() => window.results())86 t.deepEqual(results, { error: false })87 }88)89test.serial(90 'Page.setRequestInterception should contain referer header',91 async t => {92 const { page, server } = t.context93 await page.setRequestInterception(true)94 const requests = []95 page.on('request', request => {96 if (!utils.isFavicon(request)) requests.push(request)97 request.continue()98 })99 await page.goto(server.PREFIX + '/one-style.html')100 t.true(requests[1].url().includes('/one-style.css'))101 t.true(requests[1].normalizedHeaders().referer.includes('/one-style.html'))102 }103)104test.serial(105 'Page.setRequestInterception should properly return navigation response when URL has cookies',106 async t => {107 const { page, server } = t.context108 // Setup cookie.109 await page.goto(server.EMPTY_PAGE)110 await page.setCookie({ name: 'foo', value: 'bar' })111 // Setup request interception.112 await page.setRequestInterception(true)113 page.on('request', request => request.continue())114 const response = await page.reload()115 t.is(response.status(), 200)116 }117)118test.serial('Page.setRequestInterception should stop intercepting', async t => {119 const { page, server } = t.context120 await page.setRequestInterception(true)121 page.once('request', request => request.continue())122 await page.goto(server.EMPTY_PAGE)123 await page.setRequestInterception(false)124 await page.goto(server.EMPTY_PAGE)125 t.pass()126})127test.serial(128 'Page.setRequestInterception should show custom HTTP headers',129 async t => {130 const { page, server } = t.context131 await page.setExtraHTTPHeaders({132 foo: 'bar'133 })134 await page.setRequestInterception(true)135 page.on('request', request => {136 t.is(request.headers()['foo'], 'bar')137 request.continue()138 })139 const response = await page.goto(server.EMPTY_PAGE)140 t.true(response.ok())141 }142)143test.serial(144 'Page.setRequestInterception should works with customizing referer headers',145 async t => {146 const { page, server } = t.context147 await page.setExtraHTTPHeaders({ referer: server.EMPTY_PAGE })148 await page.setRequestInterception(true)149 page.on('request', request => {150 t.is(request.headers()['referer'], server.EMPTY_PAGE)151 request.continue()152 })153 const response = await page.goto(server.EMPTY_PAGE)154 t.true(response.ok())155 }156)157test.serial('Page.setRequestInterception should be abortable', async t => {158 const { page, server } = t.context159 await page.setRequestInterception(true)160 page.on('request', request => {161 if (request.url().endsWith('.css')) request.abort()162 else request.continue()163 })164 let failedRequests = 0165 page.on('requestfailed', event => ++failedRequests)166 const response = await page.goto(server.PREFIX + '/one-style.html')167 t.true(response.ok())168 t.falsy(response.request().failure())169 t.is(failedRequests, 1)170})171test.serial.skip(172 'Page.setRequestInterception should be abortable with custom error codes',173 async t => {174 const { page, server } = t.context175 await page.goto(server.EMPTY_PAGE)176 let failedRequest = null177 page.on('requestfailed', request => (failedRequest = request))178 page.on('request', request => {179 request.abort('internetdisconnected')180 })181 await page.setRequestInterception(true)182 await page.evaluate(183 url =>184 fetch(url, {185 method: 'GET'186 }),187 server.EMPTY_PAGE188 )189 t.pass()190 t.truthy(failedRequest)191 t.is(failedRequest.failure().errorText, 'net::ERR_INTERNET_DISCONNECTED')192 }193)194test.serial('Page.setRequestInterception should send referer', async t => {195 const { page, server } = t.context196 await page.setExtraHTTPHeaders({197 referer: 'http://google.com/'198 })199 await page.setRequestInterception(true)200 page.on('request', request => request.continue())201 const [request] = await Promise.all([202 server.waitForRequest('/grid.html'),203 page.goto(server.PREFIX + '/grid.html')204 ])205 t.is(request.headers['referer'], 'http://google.com/')206})207test.serial(208 'Page.setRequestInterception should fail navigation when aborting main resource',209 async t => {210 const { page, server } = t.context211 await page.setRequestInterception(true)212 page.on('request', request => request.abort())213 let error = null214 await page.goto(server.EMPTY_PAGE).catch(e => (error = e))215 t.truthy(error)216 t.true(error.message.includes('net::ERR_FAILED'))217 }218)219test.serial(220 'Page.setRequestInterception should work with redirects',221 async t => {222 const { page, server } = t.context223 await page.setRequestInterception(true)224 const requests = []225 page.on('request', request => {226 request.continue()227 requests.push(request)228 })229 const response = await page.goto(server.PREFIX + '/non-existing-page.html')230 t.is(response.status(), 200)231 t.true(response.url().includes('empty.html'))232 t.is(requests.length, 5)233 t.is(requests[2].resourceType(), 'document')234 // Check redirect chain235 const redirectChain = response.request().redirectChain()236 t.is(redirectChain.length, 4)237 t.true(redirectChain[0].url().includes('/non-existing-page.html'))238 t.true(redirectChain[2].url().includes('/non-existing-page-3.html'))239 for (let i = 0; i < redirectChain.length; ++i) {240 const request = redirectChain[i]241 t.true(request.isNavigationRequest())242 t.is(request.redirectChain().indexOf(request), i)243 }244 }245)246test.serial(247 'Page.setRequestInterception should work with redirects for subresources',248 async t => {249 const { page, server } = t.context250 await page.setRequestInterception(true)251 const requests = []252 page.on('request', request => {253 request.continue()254 if (!utils.isFavicon(request)) requests.push(request)255 })256 const response = await page.goto(server.PREFIX + '/redir-css.html')257 t.is(response.status(), 200)258 t.true(response.url().includes('redir-css.html'))259 t.is(requests.length, 5)260 t.is(requests[0].resourceType(), 'document')261 t.is(requests[1].resourceType(), 'stylesheet')262 // Check redirect chain263 const redirectChain = requests[1].redirectChain()264 t.is(redirectChain.length, 3)265 t.true(redirectChain[0].url().includes('/style-redir-1.css'))266 t.true(redirectChain[2].url().includes('/style-redir-3.css'))267 }268)269test.serial(270 'Page.setRequestInterception should be able to abort redirects',271 async t => {272 const { page, server } = t.context273 await page.setRequestInterception(true)274 page.on('request', request => {275 if (request.url().includes('non-existing-2')) request.abort()276 else request.continue()277 })278 await page.goto(server.EMPTY_PAGE)279 const result = await page.evaluate(async () => {280 try {281 await fetch('/non-existing.json')282 } catch (e) {283 return e.message284 }285 })286 t.true(result.includes('Failed to fetch'))287 }288)289test.serial(290 'Page.setRequestInterception should work with equal requests',291 async t => {292 const { page, server } = t.context293 await page.goto(server.EMPTY_PAGE)294 await page.setRequestInterception(true)295 let spinner = false // Cancel 2nd request.296 page.on('request', request => {297 if (utils.isFavicon(request)) {298 request.continue()299 return300 }301 spinner ? request.abort() : request.continue()302 spinner = !spinner303 })304 const results = await page.evaluate(() =>305 Promise.all([306 fetch('/zzz')307 .then(response => response.text())308 .catch(e => 'FAILED'),309 fetch('/zzz')310 .then(response => response.text())311 .catch(e => 'FAILED'),312 fetch('/zzz')313 .then(response => response.text())314 .catch(e => 'FAILED')315 ])316 )317 t.deepEqual(results, ['zzz', 'FAILED', 'zzz'])318 }319)320test.serial(321 'Page.setRequestInterception should navigate to dataURL and fire dataURL requests',322 async t => {323 const { page, server } = t.context324 await page.setRequestInterception(true)325 const requests = []326 page.on('request', request => {327 requests.push(request)328 request.continue()329 })330 const dataURL = 'data:text/html,<div>yo</div>'331 const response = await page.goto(dataURL)332 t.is(response.status(), 200)333 t.is(requests.length, 1)334 t.is(requests[0].url(), dataURL)335 }336)337test.serial(338 'Page.setRequestInterception should navigate to URL with hash and and fire requests with hash',339 async t => {340 const { page, server } = t.context341 await page.setRequestInterception(true)342 const requests = []343 page.on('request', request => {344 requests.push(request)345 request.continue()346 })347 const response = await page.goto(server.EMPTY_PAGE + '#hash')348 t.is(response.status(), 200)349 t.is(response.url(), server.EMPTY_PAGE)350 t.is(requests.length, 1)351 t.is(requests[0].url(), server.EMPTY_PAGE + '#hash')352 }353)354test.serial(355 'Page.setRequestInterception should work with encoded server',356 async t => {357 const { page, server } = t.context358 // The requestWillBeSent will report encoded URL, whereas interception will359 // report URL as-is. @see crbug.com/759388360 await page.setRequestInterception(true)361 page.on('request', request => request.continue())362 const response = await page.goto(server.PREFIX + '/some nonexisting page')363 t.is(response.status(), 404)364 }365)366test.serial(367 'Page.setRequestInterception should work with badly encoded server',368 async t => {369 const { page, server } = t.context370 await page.setRequestInterception(true)371 page.on('request', request => request.continue())372 const response = await page.goto(server.PREFIX + '/malformed?rnd=%911')373 t.is(response.status(), 200)374 }375)376test.serial(377 'Page.setRequestInterception should work with encoded server - 2',378 async t => {379 const { page, server } = t.context380 // The requestWillBeSent will report URL as-is, whereas interception will381 // report encoded URL for stylesheet. @see crbug.com/759388382 await page.setRequestInterception(true)383 const requests = []384 page.on('request', request => {385 request.continue()386 requests.push(request)387 })388 const response = await page.goto(389 `data:text/html,<link rel="stylesheet" href="${390 server.PREFIX391 }/fonts?helvetica|arial"/>`392 )393 t.is(response.status(), 200)394 t.is(requests.length, 2)395 t.is(requests[1].response().status(), 404)396 }397)398test.serial(399 'Page.setRequestInterception should not throw "Invalid Interception Id" if the request was cancelled',400 async t => {401 const { page, server } = t.context402 await page.setContent('<iframe></iframe>')403 await page.setRequestInterception(true)404 let request = null405 page.on('request', r => (request = r))406 page.$eval('iframe', (frame, url) => (frame.src = url), server.EMPTY_PAGE) // Wait for request interception.407 await utils.waitEvent(page, 'request') // Delete frame to cause request to be canceled.408 await page.$eval('iframe', frame => frame.remove())409 let error = null410 await request.continue().catch(e => (error = e))411 t.falsy(error)412 }413)414test.serial(415 'Page.setRequestInterception should throw if interception is not enabled',416 async t => {417 const { page, server } = t.context418 let error = null419 page.on('request', async request => {420 try {421 await request.continue()422 } catch (e) {423 error = e424 }425 })426 await page.goto(server.EMPTY_PAGE)427 t.true(error.message.includes('Request Interception is not enabled'))428 }429)430test.serial(431 'Page.setRequestInterception should work with file URLs',432 async t => {433 const { page, server } = t.context434 await page.setRequestInterception(true)435 const urls = new Set()436 page.on('request', request => {437 urls.add(438 request439 .url()440 .split('/')441 .pop()442 )443 request.continue()444 })445 await page.goto(pathToFileURL(utils.assetPath('one-style.html')))446 t.is(urls.size, 2)447 t.true(urls.has('one-style.html'))448 t.true(urls.has('one-style.css'))449 }450)451test.serial('Request.continue should work', async t => {452 const { page, server } = t.context453 await page.setRequestInterception(true)454 page.on('request', request => request.continue())455 await page.goto(server.EMPTY_PAGE)456 t.pass()457})458test.serial('Request.continue should amend HTTP headers', async t => {459 const { page, server } = t.context460 await page.setRequestInterception(true)461 page.on('request', request => {462 const headers = Object.assign({}, request.headers())463 headers['FOO'] = 'bar'464 request.continue({ headers })465 })466 await page.goto(server.EMPTY_PAGE)467 const [request] = await Promise.all([468 server.waitForRequest('/sleep.zzz'),469 page.evaluate(() => fetch('/sleep.zzz'))470 ])471 t.is(request.headers['foo'], 'bar')472})473test.serial(474 'Request.continue should redirect in a way non-observable to page',475 async t => {476 const { page, server } = t.context477 await page.setRequestInterception(true)478 page.on('request', request => {479 const redirectURL = request.url().includes('/empty.html')480 ? server.PREFIX + '/consolelog.html'481 : undefined482 request.continue({ url: redirectURL })483 })484 let consoleMessage = null485 page.on('console', msg => (consoleMessage = msg))486 await page.goto(server.EMPTY_PAGE)487 t.is(page.url(), server.EMPTY_PAGE)488 t.is(consoleMessage.text(), 'yellow')489 }490)491test.serial('Request.continue should amend method', async t => {492 const { page, server } = t.context493 await page.goto(server.EMPTY_PAGE)494 await page.setRequestInterception(true)495 page.on('request', request => {496 request.continue({ method: 'POST' })497 })498 const [request] = await Promise.all([499 server.waitForRequest('/sleep.zzz'),500 page.evaluate(() => fetch('/sleep.zzz'))501 ])502 t.is(request.req.method, 'POST')503})504test.serial('Request.continue should amend post data', async t => {505 const { page, server } = t.context506 await page.goto(server.EMPTY_PAGE)507 await page.setRequestInterception(true)508 page.on('request', request => {509 request.continue({ postData: 'doggo' })510 })511 const [request] = await Promise.all([512 server.waitForRequest('/sleep.zzz'),513 page.evaluate(() =>514 fetch('/sleep.zzz', {515 method: 'POST',516 body: 'birdy'517 })518 )519 ])520 t.is(request.body, 'doggo')521})522test.serial(523 'Request.continue should amend both post data and method on navigation',524 async t => {525 const { page, server } = t.context526 await page.goto(server.EMPTY_PAGE)527 await page.setRequestInterception(true)528 page.on('request', request => {529 request.continue({ method: 'POST', postData: 'doggo' })530 })531 const [request] = await Promise.all([532 server.waitForRequest('/sleep.zzz'),533 page.evaluate(() =>534 fetch('/sleep.zzz', {535 method: 'POST',536 body: 'birdy'537 })538 )539 ])540 // t.log(serverRequest.req)541 t.is(request.body, 'doggo')542 t.is(request.raw.method, 'POST')543 }544)545test.serial('Request.respond should work', async t => {546 const { page, server } = t.context547 await page.setRequestInterception(true)548 page.on('request', request => {549 request.respond({550 status: 201,551 headers: {552 foo: 'bar'553 },554 body: 'Yo, page!'555 })556 })557 const response = await page.goto(server.EMPTY_PAGE)558 t.is(response.status(), 201)559 t.is(response.headers().foo, 'bar')560 const testResult = await page.evaluate(() => document.body.textContent)561 t.is(testResult, 'Yo, page!')562})563test.serial('Request.respond should redirect', async t => {564 const { page, server } = t.context565 await page.setRequestInterception(true)566 page.on('request', request => {567 if (!request.url().includes('rrredirect')) {568 request.continue()569 return570 }571 request.respond({572 status: 302,573 headers: {574 location: server.EMPTY_PAGE575 }576 })577 })578 const response = await page.goto(server.PREFIX + '/rrredirect')579 t.is(response.request().redirectChain().length, 1)580 t.is(581 response582 .request()583 .redirectChain()[0]584 .url(),585 server.PREFIX + '/rrredirect'586 )587 t.is(response.url(), server.EMPTY_PAGE)588})589test.serial(590 'Request.respond should allow mocking binary responses',591 async t => {592 const { page, server } = t.context593 await page.setRequestInterception(true)594 page.on('request', request => {595 const imageBuffer = fs.readFileSync(utils.assetPath('pptr.png'))596 request.respond({597 contentType: 'image/png',598 body: imageBuffer599 })600 })601 await page.evaluate(PREFIX => {602 const img = document.createElement('img')603 img.src = PREFIX + '/does-not-exist.png'604 document.body.appendChild(img)605 return new Promise(fulfill => (img.onload = fulfill))606 }, server.PREFIX)607 const img = await page.$('img')...
router.test.js
Source:router.test.js
...53//posting movie from premium user, server should respond with a 201 status54test("Posting movie from premium user, server should respond with a 201 status.", async () => {55 const browser = await puppeteer.launch({headless: true});56 const page = await browser.newPage();57 await page.setRequestInterception(true);58 let data = {59 title: "Movie6",60 test: "true",61 user: "premium"62 }63 page.on("request", request => {64 let payload = {65 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},66 "method": "POST",67 "postData": JSON.stringify(data)68 }69 request.continue(payload);70 });71 const response = await page.goto(`${host}:${port}/movies`);72 const responseBody = await response.text();73 await browser.close();74 expect(response._status).toBe(201);75});76//posting movie from basic user that hasn't met his limit, server should respond with a 201 status77test("Posting movie from basic user that hasn't met his limit, server should respond with a 201 status.", async () => {78 const browser = await puppeteer.launch({headless: true});79 const page = await browser.newPage();80 await page.setRequestInterception(true);81 let data = {82 title: "Movie6",83 test: "true",84 user: "premium"85 }86 page.on("request", request => {87 let payload = {88 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},89 "method": "POST",90 "postData": JSON.stringify(data)91 }92 request.continue(payload);93 });94 const response = await page.goto(`${host}:${port}/movies`);95 await browser.close();96 expect(response._status).toBe(201);97});98//Posting movie from basic user that has met his limit, server should respond with a 403 status99test("Posting movie from basic user that has met his limit, server should respond with a 403 status.", async () => {100 const browser = await puppeteer.launch({headless: true});101 const page = await browser.newPage();102 await page.setRequestInterception(true);103 let data = {104 title: "Movie6",105 test: "true",106 user: "basic_full"107 }108 page.on("request", request => {109 let payload = {110 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},111 "method": "POST",112 "postData": JSON.stringify(data)113 }114 request.continue(payload);115 });116 const response = await page.goto(`${host}:${port}/movies`);117 await browser.close();118 expect(response._status).toBe(403);119});120//User has sent invalid authentication token, should receive 403 status.121test("User has sent invalid authentication token, should receive 403 status.", async () => {122 const browser = await puppeteer.launch({headless: true});123 const page = await browser.newPage();124 await page.setRequestInterception(true);125 let data = {126 test: true,127 title: "Movie6"128 }129 page.on("request", request => {130 let payload = {131 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test_invalid"},132 "method": "POST",133 "postData": JSON.stringify(data)134 }135 request.continue(payload);136 });137 const response = await page.goto(`${host}:${port}/movies`);138 await browser.close();139 expect(response._status).toBe(403);140});141//User has sent no authentication token, should receive a 401 status.142test("User has sent no authentication token, should receive a 401 status.", async () => {143 const browser = await puppeteer.launch({headless: true});144 const page = await browser.newPage();145 await page.setRequestInterception(true);146 let data = {147 test: true,148 title: "Movie6"149 }150 page.on("request", request => {151 let payload = {152 "headers": {...request.headers(), "content-type": "application/json"},153 "method": "POST",154 "postData": JSON.stringify(data)155 }156 request.continue(payload);157 });158 const response = await page.goto(`${host}:${port}/movies`);159 await browser.close();160 expect(response._status).toBe(401);161});162//User has sent no title in the payload, should receive a 400 status.163test("User has sent no title in the payload, should receive a 400 status.", async () => {164 const browser = await puppeteer.launch({headless: true});165 const page = await browser.newPage();166 await page.setRequestInterception(true);167 let data = {168 test: true,169 title: "",170 user: "basic_full"171 }172 page.on("request", request => {173 let payload = {174 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},175 "method": "POST",176 "postData": JSON.stringify(data)177 }178 request.continue(payload);179 });180 const response = await page.goto(`${host}:${port}/movies`);181 await browser.close();182 expect(response._status).toBe(400);183});184//User typed everything properly, but server couldn't find an item, responding with 404 status. Testing basic account.185test("User typed everything properly, but server couldn't find an item, responding with 404 status.", async () => {186 const browser = await puppeteer.launch({headless: true});187 const page = await browser.newPage();188 await page.setRequestInterception(true);189 let data = {190 test: true,191 title: "Meofjwp2",192 user: "basic_not_full"193 }194 page.on("request", request => {195 let payload = {196 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},197 "method": "POST",198 "postData": JSON.stringify(data)199 }200 request.continue(payload);201 });202 const response = await page.goto(`${host}:${port}/movies`);203 await browser.close();204 expect(response._status).toBe(404);205});206//User typed everything properly, but server couldn't find an item, responding with 404 status. Testing premium account.207test("User typed everything properly, but server couldn't find an item, responding with 404 status.", async () => {208 const browser = await puppeteer.launch({headless: true});209 const page = await browser.newPage();210 await page.setRequestInterception(true);211 let data = {212 test: true,213 title: "Meofjwp2",214 user: "premium"215 }216 page.on("request", request => {217 let payload = {218 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},219 "method": "POST",220 "postData": JSON.stringify(data)221 }222 request.continue(payload);223 });224 const response = await page.goto(`${host}:${port}/movies`);225 await browser.close();226 expect(response._status).toBe(404);227});228//User wanted to add a duplicate. Server should respond with 412 status.229test("User wanted to add a duplicate. Server should respond with 412 status.", async () => {230 const browser = await puppeteer.launch({headless: true});231 const page = await browser.newPage();232 await page.setRequestInterception(true);233 let data = {234 test: true,235 title: "Movie2",236 user: "premium"237 }238 page.on("request", request => {239 let payload = {240 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},241 "method": "POST",242 "postData": JSON.stringify(data)243 }244 request.continue(payload);245 });246 const response = await page.goto(`${host}:${port}/movies`);247 await browser.close();248 expect(response._status).toBe(412);249});250//Forcing server to respond with a 500 error.251test("Forcing server to respond with an 500 error.", async () => {252 const browser = await puppeteer.launch({headless: true});253 const page = await browser.newPage();254 await page.setRequestInterception(true);255 let data = {256 test: true,257 title: "Movie2",258 user: "premium",259 induce_error: true,260 }261 page.on("request", request => {262 let payload = {263 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test"},264 "method": "POST",265 "postData": JSON.stringify(data)266 }267 request.continue(payload);268 });269 const response = await page.goto(`${host}:${port}/movies`);270 await browser.close();271 expect(response._status).toBe(500);272});273//Requesting rubbish.274test("Requesting rubbish test 01", async () => {275 const browser = await puppeteer.launch({headless: true});276 const page = await browser.newPage();277 await page.setRequestInterception(true);278 let data = {279 test: true,280 title: "M34cr34rc34rx3",281 user: "pr23rs34r3cx4tv54y74y65yv56v",282 induce_error: "rx'34rc34tncb4398 bn",283 }284 page.on("request", request => {285 let payload = {286 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "re eig uerpm iuerhtp veirut,hpiu"},287 "method": "POST",288 "postData": JSON.stringify(data)289 }290 request.continue(payload);291 });292 const response = await page.goto(`${host}:${port}/movies`);293 await browser.close();294 expect(response._status).toBe(403);295});296//Requesting rubbish.297test("Requesting rubbish", async () => {298 const browser = await puppeteer.launch({headless: true});299 const page = await browser.newPage();300 await page.setRequestInterception(true);301 let data = {302 test: true,303 title: "M34cr34rc34rx3",304 user: "pr23rs34r3cx4tv54y74y65yv56v"305 }306 page.on("request", request => {307 let payload = {308 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bear test"},309 "method": "POST",310 "postData": JSON.stringify(data)311 }312 request.continue(payload);313 });314 const response = await page.goto(`${host}:${port}/movies`);315 await browser.close();316 expect(response._status).toBe(404);317});318//GET /movies319//user is authenticated, so will receive a 200 status320test("Authenticated, expecting a 200 status.", async () => {321 const browser = await puppeteer.launch({headless: true});322 const page = await browser.newPage();323 await page.setRequestInterception(true);324 page.on("request", request => {325 let payload = {326 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test", "Test": "true", "User": "premium"},327 "method": "GET",328 }329 request.continue(payload);330 });331 const response = await page.goto(`${host}:${port}/movies`);332 await browser.close();333 expect(response._status).toBe(200);334});335//user has invalid token, will receive a 403 status336test("Invalid token, expecting 403 status.", async () => {337 const browser = await puppeteer.launch({headless: true});338 const page = await browser.newPage();339 await page.setRequestInterception(true);340 let data = {341 test: true342 }343 page.on("request", request => {344 let payload = {345 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer testewefewfw", "Test": "true", "User": "premium"},346 "method": "GET",347 "getData": JSON.stringify(data)348 }349 request.continue(payload);350 });351 const response = await page.goto(`${host}:${port}/movies`);352 await browser.close();353 expect(response._status).toBe(403);354});355//user has no token, will receive a 401 status356test("No token, expecting 401 status.", async () => {357 const browser = await puppeteer.launch({headless: true});358 const page = await browser.newPage();359 await page.setRequestInterception(true);360 let data = {361 test: true362 }363 page.on("request", request => {364 let payload = {365 "headers": {...request.headers(), "content-type": "application/json", "Test": "true", "User": "premium"},366 "method": "GET",367 "getData": JSON.stringify(data)368 }369 request.continue(payload);370 });371 const response = await page.goto(`${host}:${port}/movies`);372 await browser.close();373 expect(response._status).toBe(401);374});375//server stopped processing prematurely, so user will receive a 500 status376test("Forcing server to respond with an 500 error.", async () => {377 const browser = await puppeteer.launch({headless: true});378 const page = await browser.newPage();379 await page.setRequestInterception(true);380 let data = {381 test: true,382 induce_error: true,383 }384 page.on("request", request => {385 let payload = {386 "headers": {...request.headers(), "content-type": "application/json", "Authorization": "Bearer test", "Test": "true", "User": "premium", "Error": "true"},387 "method": "GET",388 "getData": JSON.stringify(data)389 }390 request.continue(payload);391 });392 const response = await page.goto(`${host}:${port}/movies`);393 await browser.close();...
proxyRequest.js
Source:proxyRequest.js
...31 });32 const httpServer = await createHttpServer(requestHandler);33 const httpProxyServer = await createHttpProxyServer();34 await createPage(async (page) => {35 await page.setRequestInterception(true);36 page.on('request', async (request) => {37 await proxyRequest({38 page,39 proxyUrl: httpProxyServer.url,40 request,41 });42 });43 const response = await page.goto(httpServer.url + '/foo');44 t.is((await response.headers())['x-foo'], 'bar');45 t.is(await page.url(), httpServer.url + '/foo');46 });47 t.true(requestHandler.called);48});49test('specify HTTP and HTTPS proxy', async (t) => {50 t.plan(3);51 const requestHandler = sinon.stub().callsFake((incomingRequest, outgoingRequest) => {52 outgoingRequest.end('foo');53 });54 const httpServer = await createHttpServer(requestHandler);55 const httpProxyServer = await createHttpProxyServer();56 await createPage(async (page) => {57 await page.setRequestInterception(true);58 page.on('request', async (request) => {59 await proxyRequest({60 page,61 proxyUrl: {62 http: httpProxyServer.url,63 https: httpProxyServer.url,64 },65 request,66 });67 });68 const response = await page.goto(httpServer.url + '/foo');69 t.is((await response.headers())['x-foo'], 'bar');70 t.is(await page.url(), httpServer.url + '/foo');71 });72 t.true(requestHandler.called);73});74test('Puppeteer handles redirects', async (t) => {75 t.plan(1);76 let requestIndex = 0;77 const requestHandler = sinon78 .stub()79 .callsFake((incomingRequest, outgoingRequest) => {80 if (++requestIndex < 3) {81 outgoingRequest.writeHead(301, {82 location: '/' + requestIndex,83 });84 outgoingRequest.end();85 } else {86 outgoingRequest.end(String(requestIndex));87 }88 });89 const httpServer = await createHttpServer(requestHandler);90 const httpProxyServer = await createHttpProxyServer();91 await createPage(async (page) => {92 await page.setRequestInterception(true);93 page.on('request', async (request) => {94 await proxyRequest({95 page,96 proxyUrl: httpProxyServer.url,97 request,98 });99 });100 await page.goto(httpServer.url);101 });102 t.is(requestHandler.callCount, 3);103});104test('handles HTTP errors (unreachable server)', async (t) => {105 t.plan(2);106 await createPage(async (page) => {107 await page.setRequestInterception(true);108 page.on('request', async (request) => {109 await proxyRequest({110 page,111 proxyUrl: 'http://127.0.0.1:' + await getPort(),112 request,113 });114 });115 const error = await t.throwsAsync(page.goto('http://127.0.0.1'));116 t.is(error.message, 'net::ERR_FAILED at http://127.0.0.1');117 });118});119test('sets cookies for the succeeding proxy requests', async (t) => {120 t.plan(4);121 const requestHandler = sinon.stub()122 .onCall(0)123 .callsFake((incomingRequest, outgoingRequest) => {124 outgoingRequest.setHeader('set-cookie', 'foo=bar');125 outgoingRequest.end('foo');126 })127 .onCall(1)128 .callsFake((incomingRequest, outgoingRequest) => {129 t.is(incomingRequest.headers.cookie, 'foo=bar');130 outgoingRequest.end('bar');131 });132 const httpServer = await createHttpServer(requestHandler);133 const httpProxyServer = await createHttpProxyServer();134 await createPage(async (page) => {135 await page.setRequestInterception(true);136 page.on('request', async (request) => {137 await proxyRequest({138 page,139 proxyUrl: httpProxyServer.url,140 request,141 });142 });143 t.deepEqual(await page.cookies(), []);144 await page.goto(httpServer.url);145 t.deepEqual(await page.cookies(), [146 {147 domain: 'localhost',148 expires: -1,149 httpOnly: false,150 name: 'foo',151 path: '/',152 secure: false,153 session: true,154 size: 6,155 value: 'bar',156 },157 ]);158 await page.goto(httpServer.url);159 });160 t.is(requestHandler.callCount, 2);161});162test('sets cookies for the succeeding proxy requests (ignores invalid cookies)', async (t) => {163 t.plan(4);164 const requestHandler = sinon.stub()165 .onCall(0)166 .callsFake((incomingRequest, outgoingRequest) => {167 outgoingRequest.setHeader('set-cookie', ['foo=bar;', '( ) < > @ , ; : \\ " / [ ] ? = { }bar=baz']);168 outgoingRequest.end('foo');169 })170 .onCall(1)171 .callsFake((incomingRequest, outgoingRequest) => {172 t.is(incomingRequest.headers.cookie, 'foo=bar');173 outgoingRequest.end('bar');174 });175 const httpServer = await createHttpServer(requestHandler);176 const httpProxyServer = await createHttpProxyServer();177 await createPage(async (page) => {178 await page.setRequestInterception(true);179 page.on('request', async (request) => {180 await proxyRequest({181 page,182 proxyUrl: httpProxyServer.url,183 request,184 });185 });186 t.deepEqual(await page.cookies(), []);187 await page.goto(httpServer.url);188 t.deepEqual(await page.cookies(), [189 {190 domain: 'localhost',191 expires: -1,192 httpOnly: false,193 name: 'foo',194 path: '/',195 secure: false,196 session: true,197 size: 6,198 value: 'bar',199 },200 ]);201 await page.goto(httpServer.url);202 });203 t.is(requestHandler.callCount, 2);204});205test('sets cookies for the succeeding proxy requests (correctly handles cookie expiration)', async (t) => {206 t.plan(4);207 const cookieExpirationDate = new Date(roundToMinute(Date.now() + 60 * MINUTE));208 const requestHandler = sinon.stub()209 .onCall(0)210 .callsFake((incomingRequest, outgoingRequest) => {211 outgoingRequest.setHeader('set-cookie', 'foo=bar; expires=' + cookieExpirationDate.toUTCString());212 outgoingRequest.end('foo');213 })214 .onCall(1)215 .callsFake((incomingRequest, outgoingRequest) => {216 t.is(incomingRequest.headers.cookie, 'foo=bar');217 outgoingRequest.end('bar');218 });219 const httpServer = await createHttpServer(requestHandler);220 const httpProxyServer = await createHttpProxyServer();221 await createPage(async (page) => {222 await page.setRequestInterception(true);223 page.on('request', async (request) => {224 await proxyRequest({225 page,226 proxyUrl: httpProxyServer.url,227 request,228 });229 });230 t.deepEqual(await page.cookies(), []);231 await page.goto(httpServer.url);232 const firstCookie = (await page.cookies())[0];233 t.is(roundToMinute(firstCookie.expires * 1000), roundToMinute(cookieExpirationDate.getTime()));234 await page.goto(httpServer.url);235 });236 t.is(requestHandler.callCount, 2);237});238test('inherits cookies from Page object', async (t) => {239 t.plan(2);240 const requestHandler = sinon241 .stub()242 .callsFake((incomingRequest, outgoingRequest) => {243 t.is(incomingRequest.headers.cookie, 'foo=bar');244 outgoingRequest.end('foo');245 });246 const httpServer = await createHttpServer(requestHandler);247 const httpProxyServer = await createHttpProxyServer();248 await createPage(async (page) => {249 await page.setCookie({250 domain: 'localhost',251 name: 'foo',252 value: 'bar',253 });254 await page.setRequestInterception(true);255 page.on('request', async (request) => {256 await proxyRequest({257 page,258 proxyUrl: httpProxyServer.url,259 request,260 });261 });262 await page.goto(httpServer.url);263 });264 t.is(requestHandler.callCount, 1);265});266test('inherits cookies from Page object (correctly handles cookie expiration)', async (t) => {267 t.plan(2);268 const cookieExpirationDate = new Date(roundToMinute(Date.now() + 60 * MINUTE));269 const requestHandler = sinon270 .stub()271 .callsFake((incomingRequest, outgoingRequest) => {272 t.is(incomingRequest.headers.cookie, 'foo=bar');273 outgoingRequest.end('foo');274 });275 const httpServer = await createHttpServer(requestHandler);276 const httpProxyServer = await createHttpProxyServer();277 await createPage(async (page) => {278 await page.setCookie({279 domain: 'localhost',280 expires: cookieExpirationDate / 1000,281 name: 'foo',282 value: 'bar',283 });284 await page.setRequestInterception(true);285 page.on('request', async (request) => {286 await proxyRequest({287 page,288 proxyUrl: httpProxyServer.url,289 request,290 });291 });292 await page.goto(httpServer.url);293 });294 t.is(requestHandler.callCount, 1);295});296test('downloads a binary file', async (t) => {297 t.plan(2);298 const subject = crypto.randomBytes(256);299 const requestHandler = sinon.stub().callsFake((incomingRequest, outgoingRequest) => {300 outgoingRequest.setHeader('access-control-allow-origin', '*');301 outgoingRequest.end(subject);302 });303 const httpServer = await createHttpServer(requestHandler);304 const httpProxyServer = await createHttpProxyServer();305 await createPage(async (page) => {306 await page.setRequestInterception(true);307 page.on('request', async (request) => {308 await proxyRequest({309 page,310 proxyUrl: httpProxyServer.url,311 request,312 });313 });314 const blob = await downloadBlob(page, httpServer.url);315 t.true(blob.equals(subject));316 });317 t.true(requestHandler.called);...
player.test.js
Source:player.test.js
1const fs = require('fs');2const player = require('./player');3const sanitiseConfiguration = require('../sanitiser');4jest.mock('fs', () => ({5 readFileSync: jest.fn(() => `[{6 "url": "http://www.example.com/x/?foo=bar",7 "fullPath": "http://www.example.com/x",8 "minimalPath": "http://www.example.com/x",9 "query": {10 "foo": "bar"11 },12 "headers": {13 "content-type": "application/json"14 },15 "status": 200,16 "method": "GET",17 "body": "{}"18 }]`),19}));20const configuration = sanitiseConfiguration({ fixtureName: 'fixture-name' });21describe('Player:', () => {22 it('calls handlePlayMode with correct parameters', async () => {23 const page = {24 setRequestInterception: jest.fn(),25 on: jest.fn(),26 };27 const modifiedConfig = ({ ...configuration, ...{ page, replaceImage: false } });28 await player({ browser: Object, config: modifiedConfig });29 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));30 expect(page.setRequestInterception).toHaveBeenCalledWith(true);31 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));32 });33 describe('on `request` single page', () => {34 it('Abort when resource is image and allowImageRecourses=false', async () => {35 const request = {36 resourceType: () => 'image',37 url: () => 'http://www.example.com',38 abort: jest.fn(),39 };40 const page = {41 setRequestInterception: jest.fn(),42 on: jest.fn((type, fn) => fn(request)),43 };44 const modifiedConfig = ({ ...configuration, ...{ page, replaceImage: false } });45 await player({ browser: Object, config: modifiedConfig });46 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));47 expect(page.setRequestInterception).toHaveBeenCalledWith(true);48 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));49 expect(request.abort).toHaveBeenCalled();50 });51 it('Continue when resource is image and allowImageRecourses=true', async () => {52 const request = {53 resourceType: () => 'image',54 url: () => 'http://www.example.com',55 continue: jest.fn(),56 };57 const page = {58 setRequestInterception: jest.fn(),59 on: jest.fn((type, fn) => fn(request)),60 };61 const modifiedConfig = ({ ...configuration, ...{ page, allowImageRecourses: true } });62 await player({ browser: Object, config: modifiedConfig });63 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));64 expect(page.setRequestInterception).toHaveBeenCalledWith(true);65 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));66 expect(request.continue).toHaveBeenCalled();67 });68 it('Respond when resource is image and allowImageRecourses=true', async () => {69 const request = {70 resourceType: () => 'image',71 url: () => 'http://www.example.com/x/?foo=bar',72 respond: jest.fn(),73 continue: jest.fn(),74 };75 const page = {76 setRequestInterception: jest.fn(),77 on: jest.fn((type, fn) => fn(request)),78 };79 const modifiedConfig = ({ ...configuration, ...{ page, allowImageRecourses: true } });80 await player({ browser: Object, config: modifiedConfig });81 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));82 expect(page.setRequestInterception).toHaveBeenCalledWith(true);83 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));84 expect(request.respond).not.toHaveBeenCalled();85 expect(request.continue).toHaveBeenCalled();86 });87 });88 describe('on `request` multiple pages', () => {89 it('Abort when resource is image and allowImageRecourses=false', async () => {90 const request = {91 resourceType: () => 'image',92 url: () => 'http://www.example.com',93 abort: jest.fn(),94 };95 const page = {96 setRequestInterception: jest.fn(),97 on: jest.fn((type, fn) => fn(request)),98 };99 const browser = {100 pages: () => [page, page],101 };102 await player({ browser, config: configuration });103 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));104 expect(page.setRequestInterception).toHaveBeenCalledTimes(2);105 expect(page.setRequestInterception).toHaveBeenCalledWith(true);106 expect(page.on).toHaveBeenCalledTimes(2);107 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));108 expect(request.abort).toHaveBeenCalledTimes(2);109 });110 it('Continue when resource is image and allowImageRecourses=true', async () => {111 const request = {112 resourceType: () => 'image',113 url: () => 'http://www.example.com',114 continue: jest.fn(),115 };116 const page = {117 setRequestInterception: jest.fn(),118 on: jest.fn((type, fn) => fn(request)),119 };120 const browser = {121 pages: () => [page, page],122 };123 const modifiedConfig = ({ ...configuration, ...{ allowImageRecourses: true } });124 await player({ browser, config: modifiedConfig });125 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));126 expect(page.setRequestInterception).toHaveBeenCalledTimes(2);127 expect(page.setRequestInterception).toHaveBeenCalledWith(true);128 expect(page.on).toHaveBeenCalledTimes(2);129 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));130 expect(request.continue).toHaveBeenCalledTimes(2);131 });132 it('Respond when resource is image and allowImageRecourses=true', async () => {133 const request = {134 resourceType: () => 'image',135 url: () => 'http://www.example.com/x/?foo=bar',136 respond: jest.fn(),137 };138 const page = {139 setRequestInterception: jest.fn(),140 on: jest.fn((type, fn) => fn(request)),141 };142 const browser = {143 pages: () => [page, page],144 };145 await player({ browser, config: configuration });146 expect(fs.readFileSync).toHaveBeenCalledWith(expect.stringContaining('__fixtures__'));147 expect(page.setRequestInterception).toHaveBeenCalledTimes(2);148 expect(page.setRequestInterception).toHaveBeenCalledWith(true);149 expect(page.on).toHaveBeenCalledTimes(2);150 expect(page.on).toHaveBeenCalledWith('request', expect.any(Function));151 expect(request.respond).toHaveBeenCalledTimes(2);152 });153 });...
PosterSearch.spec.js
Source:PosterSearch.spec.js
...23 )24 })25 it("tells me when we're searching", async (done) => {26 expect.assertions(3); //say there are 3 assertions in this test27 await page.setRequestInterception(true)28 page.on('request',async req=>{29 if(req.url().includes('omdbapi.com')){30 const msg = await page.$('#msg')31 await expect(msg).toMatch('Searching...')32 await req.respond({33 headers:{"Access-Control-Allow-Origin":"*"},34 body: JSON.stringify(dummyPosters), //use stubbed out response for external apis35 contentType:'application/json'36 })37 38 done()39 }40 })41 await expect(page).toFill('#movie-name','star') //order puppeteer to input 'star' into search called movie-name42 await expect(page).toClick("#search-button") //order puppeteer to click 'search-button'43 })44 xit('tells me when there are no results', () => {})45 it('handles api errors', async(done) => {46 await page.setRequestInterception(true)47 page.on('request',async req=>{48 if(req.url().includes('omdbapi.com')){49 await req.respond({50 headers:{"Access-Control-Allow-Origin":"*"},51 body:JSON.stringify(apiErrorResponse),52 contentType:"application/json"53 })54 }55 })56 page.on('response',async(res)=>{57 if(res.url().includes('omdbapi.com')){58 const msg = await page.$('#msg')59 await expect(msg).toMatch(apiErrorResponse.Error)60 await page.setRequestInterception(false)61 done()62 }63 })64 await expect(page).toFill('#movie-name','star')65 await expect(page).toClick('#search-button')66 })67 it('handles network errors', async(done) => {68 expect.assertions(3)69 await page.setRequestInterception(true)70 page.on('request',async(req)=>{71 if(req.url().includes('omdbapi.com')){72 await req.abort('failed')73 const msg = await page.$('#msg')74 await expect(msg).toMatch('Something went wrong. Please try again later.')75 await page.setRequestInterception(false)76 done()77 }78 })79 await expect(page).toFill('#movie-name','star')80 await expect(page).toClick('#search-button')81 })82 xit('tells me how many results were found and how many are being displayed', () => {})83 it('displays all results', async(done) => { //main thing app is suppose to do84 expect.assertions(12)85 await page.setRequestInterception(true)86 page.on('request',async req=>{87 if(req.url().includes('omdbapi.com')){88 if(process.env.NODE_ENV==='build'){89 await req.continue()90 }91 else{92 await req.respond({93 headers:{"Access-Control-Allow-Origin":"*"},94 body: JSON.stringify(dummyPosters), //use stubbed out response for external apis95 contentType:'application/json'96 })97 }98 }99 })100 page.on('response',async res=>{101 if(res.url().includes("omdbapi.com")){102 const results = process.env.NODE_ENV ==='build'? await res.json(): dummyPosters103 await Promise.all(104 results.Search.map(movie=>{105 return(expect(page).toMatchElement(`img[src="${movie.Poster}"]`))106 }107 )108 ).then(async ()=>{109 await page.setRequestInterception(false)110 done()111 })112 }113 })114 await expect(page).toFill('#movie-name','star')115 await expect(page).toClick('#search-button')116 })117 xit('displays a placeholder when no poster is available', () => {})...
index.js
Source:index.js
...19 'X-XSRF-TOKEN': oldXsrfToken,20 },21 });22 });23 await page.setRequestInterception(true);24 await page.goto('https://www.epicgames.com/id/api/authenticate');25 await page.setRequestInterception(false);26 27 page.once('request', (req) => {28 req.continue({29 method: 'GET',30 headers: {31 ...req.headers,32 'X-XSRF-TOKEN': oldXsrfToken,33 },34 });35 });36 await page.setRequestInterception(true);37 try {38 await page.goto('https://www.epicgames.com/id/api/csrf');39 } catch (e) {}40 await page.setRequestInterception(false);41 42 const xsrfToken = (await page.cookies()).find((c) => c.name === 'XSRF-TOKEN').value;43 page.once('request', (req) => {44 req.continue({45 method: 'POST',46 headers: {47 ...req.headers,48 'X-XSRF-TOKEN': xsrfToken,49 },50 });51 });52 await page.setRequestInterception(true);53 const response = await (await page.goto('https://www.epicgames.com/id/api/exchange/generate')).json();54 await page.setRequestInterception(false);55 if (!response.code) {56 throw new ExchangeCodeException(`Unexcepted response: ${JSON.stringify(response)}`);57 }58 return response.code;59 } catch (error) {60 if (error instanceof ExchangeCodeException) {61 throw error;62 }63 throw new ExchangeCodeException(`Exchange code cannot be obtained (${error.toString()})`);64 }65 }66 static async init (credentials={}, userOptions={}) {67 const options = {68 language: 'en-US',...
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 await context.setRequestInterception(true);6 context.route('**/*', route => {7 route.continue();8 });9 const page = await context.newPage();10 await page.screenshot({ path: 'google.png' });11 await browser.close();12})();13import { chromium } from 'playwright';14(async () => {15 const browser = await chromium.launch();16 const context = await browser.newContext();17 await context.setRequestInterception(true);18 context.route('**/*', route => {19 route.continue();20 });21 const page = await context.newPage();22 await page.screenshot({ path: 'google.png' });23 await browser.close();24})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 await context.setRequestInterception(true);6 context.route('**', (route) => {7 console.log(route.request().url());8 route.continue();9 });10 const page = await context.newPage();11 await browser.close();12})();13const { chromium } = require('playwright');14(async () => {15 const browser = await chromium.launch();16 const context = await browser.newContext();17 await context.setRequestInterception(true);18 context.route('**', (route) => {19 console.log(route.request().url());20 route.continue();21 });22 const page = await context.newPage();23 await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27 const browser = await chromium.launch();28 const context = await browser.newContext();29 await context.setRequestInterception(true);30 context.route('**', (route) => {31 console.log(route.request().url());32 route.continue();33 });34 const page = await context.newPage();35 await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39 const browser = await chromium.launch();40 const context = await browser.newContext();41 await context.setRequestInterception(true);42 context.route('**', (route) => {43 console.log(route.request().url());44 route.continue();45 });46 const page = await context.newPage();47 await browser.close();48})();49const { chromium } = require('playwright');50(async () => {51 const browser = await chromium.launch();52 const context = await browser.newContext();53 await context.setRequestInterception(true);54 context.route('**', (route) => {
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext({ recordVideo: { dir: 'videos/' } });5 const page = await context.newPage();6 await page.setRequestInterception(true);7 page.on('request', (request) => {8 if (request.url().endsWith('.png') || request.url().endsWith('.jpg'))9 request.abort();10 request.continue();11 });12 await page.screenshot({ path: 'example.png' });13 await browser.close();14})();15const { chromium } = require('playwright');16(async () => {17 const browser = await chromium.launch();18 const context = await browser.newContext({ recordVideo: { dir: 'videos/' } });19 const page = await context.newPage();20 await page.screenshot({ path: 'example.png' });21 await browser.close();22})();23const { chromium } = require('playwright');24(async () => {25 const browser = await chromium.launch();26 const context = await browser.newContext({ recordVideo: { dir: 'videos/' } });27 const page = await context.newPage();28 await page.screenshot({ path: 'example.png' });29 await browser.close();30})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({ headless: false });4 const context = await browser.newContext({5 recordVideo: {6 }7 });8 const page = await context.newPage();9 await page.setRequestInterception(true);10 page.on('request', request => {11 if (request.url().endsWith('.png') || request.url().endsWith('.jpg'))12 request.abort();
Using AI Code Generation
1const playwright = require('playwright');2const browser = await playwright.chromium.launch();3const context = await browser.newContext();4await context.setRequestInterception(true);5context.route('**/*', route => {6 if(route.request().url().endsWith('.png')){7 route.abort();8 }else{9 route.continue();10 }11});12const page = await context.newPage();13await page.screenshot({ path: 'example.png' });14await browser.close();15const playwright = require('playwright');16const browser = await playwright.chromium.launch();17const context = await browser.newContext();18await context.emulateNetworkThrottling({19});20const page = await context.newPage();21await page.screenshot({ path: 'example.png' });22await browser.close();23const playwright = require('playwright');24const browser = await playwright.chromium.launch();25const context = await browser.newContext();26await context.emulate(playwright.devices['iPhone 6']);27const page = await context.newPage();28await page.screenshot({ path: 'example.png' });29await browser.close();30const playwright = require('
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 await context.setRequestInterception(true);6 context.on('request', request => {7 request.continue({8 headers: {9 ...request.headers(),10 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'11 }12 });13 });14 const page = await context.newPage();15 await page.screenshot({ path: `example.png` });16 await browser.close();17})();
Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 await context.setRequestInterception(true);6 context.on('request', (request) => {7 request.continue({8 headers: {9 ...request.headers(),10 },11 });12 });13 const page = await context.newPage();14 await page.screenshot({ path: 'example.png' });15 await browser.close();16})();
Using AI Code Generation
1const { webkit } = require('playwright');2(async () => {3 const browser = await webkit.launch({ headless: false });4 const context = await browser.newContext();5 await context.setRequestInterception(true);6 context.route('**', (route, request) => {7 route.continue({8 headers: {9 ...request.headers(),10 },11 });12 });13 const page = await context.newPage();14 await browser.close();15})();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!