Testing using Puppeteer







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 .







, , . : unit



- . , .







?



, , . .







β€” . - - , . , , , - .







, β€” ( , ). , , . utils



- ( ).







, , β€” ! , , .







Puppeteer



, , , , . 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/');
});
      
      





:







  1. ;
  2. API redirectUrl



    ;
  3. 100 ;
  4. , .


, , 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:







  1. Node, , β€” ;
  2. , Puppeteer, β€” , , β€” -.


, . API Puppeteer «» . , evaluate



.







, - , Puppeteer, .













.







console.log





- :







console.log('Hello from main.js!');
      
      





#button2



.







:







  1. , ;
  2. β€” Β«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!');
  });
});
      
      





:







  1. console.log



    ( );
  2. 2;
  3. , 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 :







loading ...









Puppeteer, ( ) , . , .







, , . , : .







!




















All Articles