Do you love tests as I love them: with every fiber of your soul, with all the passion and enthusiasm that a developer who is greedy for full code coverage is capable of?
Puppeteer β , β . Puppeteer, , .
, Puppeteer .
?
, , . .
β . - - , . , , , - .
, β ( , ). , , . utils
- ( ).
, , β ! , , .
Puppeteer
, , puppeteer-showcase
.
: cookie
, localStorage
. ., β .
Mocha
describe('Puppeteer test cases', () => { // (127.0.0.1:5000) beforeEach(async () => { this.browser = await puppeteer.launch({ // UI , headless . headless: true, }); this.page = await this.browser.newPage(); await this.page.goto('http://127.0.0.1:5000/'); }); // afterEach(async () => { await this.browser.close(); }); // });
, : . β !
timeout?
, (#button1
), :
let redirectUrl = 'https://example.com/default/url/'; try { const response = await fetch('https://example.com/api/some/endpoint/?with=params'); redirectUrl = await response.json(); } catch (exc) { console.log(exc); } window.location = redirectUrl;
URL, . URL .
:
- β API
redirectUrl
; - β API , ;
- β API (, JSON).
:
describe('button1 test cases', () => { it('should follow returned redirectUrl if response is ok', async () => { this.page.on('request', (request) => { if (request.url().endsWith('/api/some/endpoint/?with=params')) { request.respond({ status: 200, contentType: 'application/json', body: JSON.stringify('https://example.com/returned/redirect/url/'), }); } else { request.continue(); } }); this.page.setRequestInterception(true); this.page.click('#button1'); await new Promise(resolve => setTimeout(resolve, 100)); expect(this.page.url()).to.equal('https://example.com/returned/redirect/url/'); }); it('should follow default url if request is blocked', async () => { this.page.on('request', (request) => { if (request.url().endsWith('/api/some/endpoint/?with=params')) { request.abort('blockedbyclient'); } else { request.continue(); } }); this.page.setRequestInterception(true); this.page.click('#button1'); await new Promise(resolve => setTimeout(resolve, 100)); expect(this.page.url()).to.equal('https://example.com/default/url/'); }); it('should follow default url if request is invalid', async () => { this.page.on('request', (request) => { if (request.url().endsWith('/api/some/endpoint/?with=params')) { request.respond({ status: 500, contentType: 'text/html', body: '<p>Error</p>', }); } else { request.continue(); } }); this.page.setRequestInterception(true); this.page.click('#button1'); await new Promise(resolve => setTimeout(resolve, 100)); expect(this.page.url()).to.equal('https://example.com/default/url/'); }); });
Chai
, . :
it('should follow returned redirectUrl if response is ok', async () => { // this.page.on('request', (request) => { // API, 200 redirectUrl JSON if (request.url().endsWith('/api/some/endpoint/?with=params')) { request.respond({ status: 200, contentType: 'application/json', body: JSON.stringify('https://example.com/returned/redirect/url/'), }); } else { // API, request.continue(); } }); this.page.setRequestInterception(true); // this.page.click('#button1'); // 100 , await new Promise(resolve => setTimeout(resolve, 100)); // , expect(this.page.url()).to.equal('https://example.com/returned/redirect/url/'); });
:
- ;
- API
redirectUrl
; - 100 ;
- , .
, , 100 ? , 1 ? , ? , ?
: . Puppeteer API
, , - . waitForNavigation
. , .
:
it('should follow returned redirectUrl if response is ok', async () => { // this.page.on('request', (request) => { // API, 200 redirectUrl JSON if (request.url().endsWith('/api/some/endpoint/?with=params')) { request.respond({ status: 200, contentType: 'application/json', body: JSON.stringify('https://example.com/returned/redirect/url/'), }); } else { // API, request.continue(); } }); this.page.setRequestInterception(true); // this.page.click('#button1'); // , await this.page.waitForNavigation(); // , expect(this.page.url()).to.equal('https://example.com/returned/redirect/url/'); });
!
, . , await
-: , . , CI , .
JavaScript- Puppeteer:
- Node, , β ;
- , Puppeteer, β , , β -.
, . API Puppeteer «» . , evaluate
.
, - , Puppeteer, .
.
console.log
- :
console.log('Hello from main.js!');
#button2
.
:
- , ;
- β Β«Hello from main.js!Β».
:
describe('button2 test cases', () => { it('should not print message to node console on button2 click', async () => { const printedMessages = []; // console.log - console.log = (message) => { printedMessages.push(message); } // , await this.page.click('#button2'); // , expect(printedMessages).to.be.empty; }); it('should print message to browser console on button2 click', async () => { // console.log - await this.page.evaluate(() => { window.printedMessages = []; window.console.log = (message) => { window.printedMessages.push(message); } }); // , await this.page.click('#button2'); // console.log const printedMessages = await this.page.evaluate(() => window.printedMessages); // , expect(printedMessages).to.contain('Hello from main.js!'); }); });
:
-
console.log
( ); - 2;
- ,
console.log
.
:
should not print message to node console on button2 click
should print message to browser console on button2 click
, , .
Puppeteer
Puppeteer β . , ?
this.browser = await puppeteer.launch({ headless: true, // <-- });
headless: true
, ( ) , .
:
this.browser = await puppeteer.launch({ headless: false, // <-- slowMo: 500, // <-- 500 });
, , Puppeteer :
Puppeteer, ( ) , . , .
!