39
Protractor framework – how to make stable e2e tests for Angular applications

Protractor framework – how to make stable e2e tests for Angular applications

Embed Size (px)

Citation preview

Page 1: Protractor framework – how to make stable e2e tests for Angular applications

Protractor framework – how to make stable e2e tests for Angular applications

Page 2: Protractor framework – how to make stable e2e tests for Angular applications

Ludmila NesvitiyQA Automation Engineer

https://github.com/ludmilanesvitiyhttps://ua.linkedin.com/in/[email protected]

Page 3: Protractor framework – how to make stable e2e tests for Angular applications

Choosing a testing strategy

Page 4: Protractor framework – how to make stable e2e tests for Angular applications

E2E approach

Separation On reusing components, parts, functions

Describing Each test-case

Writing Easy to read and run

Supporting Easy to support and rewrite

Page 5: Protractor framework – how to make stable e2e tests for Angular applications

Optimal coverage

quantity e2e / time for runningmanual tests => mindifferent goals = different testing scope

Customer: “Automate everything”

PM:“Automate everything, that you can”

QA:“I can automate everything,

but i know my priorities”

Page 6: Protractor framework – how to make stable e2e tests for Angular applications

Test-cases priorities

Page 7: Protractor framework – how to make stable e2e tests for Angular applications

Protractor framework

Page 8: Protractor framework – how to make stable e2e tests for Angular applications

5 main points

➢ Performance

➢ Stability

➢ Timeouts

➢ Testing different modules

➢ Supporting

Page 9: Protractor framework – how to make stable e2e tests for Angular applications

Performance

1

Page 10: Protractor framework – how to make stable e2e tests for Angular applications

Protractor.conf

specs: ['../test/**/*.e2e-spec.ts'],exclude: ['../test/**/needToExclude.e2e-spec.ts'],framework: 'jasmine',allScriptsTimeout: 110000,directConnect: true

Page 11: Protractor framework – how to make stable e2e tests for Angular applications

multiCapabilities

multiCapabilities: [ {browserName: 'chrome'}, {browserName: 'firefox'}, {browserName: 'internet explorer'}],

Page 12: Protractor framework – how to make stable e2e tests for Angular applications

shardTestFiles + maxInstances

multiCapabilities: [{ browserName: 'chrome', shardTestFiles: true, maxInstances: 1 }, { browserName: 'firefox', shardTestFiles: true, maxInstances: 3 }, { browserName: 'internet explorer', shardTestFiles: false, maxInstances: 4 }],

Page 13: Protractor framework – how to make stable e2e tests for Angular applications

count

Page 14: Protractor framework – how to make stable e2e tests for Angular applications

useAllAngular2AppRoots

Page 15: Protractor framework – how to make stable e2e tests for Angular applications

Stability

2

Page 16: Protractor framework – how to make stable e2e tests for Angular applications

onPrepare: function ()

onPrepare: () => { browser.ignoreSynchronization = true; browser.driver.manage().window().maximize(); jasmine.getEnv().addReporter(new SpecReporter());}

Page 17: Protractor framework – how to make stable e2e tests for Angular applications

Cloud services

const browserstackUser = process.env.BROWSERSTACK_USERNAME;const browserstackKey = process.env.BROWSERSTACK_KEY;

exports.config = { multiCapabilities: [{ 'browserstack.user': browserstackUser, 'browserstack.key': browserstackKey, 'browserName': 'internet explorer', 'browser_version': '10' }]};

Page 18: Protractor framework – how to make stable e2e tests for Angular applications

PROMISES

Page 19: Protractor framework – how to make stable e2e tests for Angular applications

Timeouts

3

Page 20: Protractor framework – how to make stable e2e tests for Angular applications

Wait - how much, why and where?

browser.get(address, timeout); // Default = 10

allScriptsTimeout: timeout; // Default = 11

getPageTimeout: timeout; // Default = 10

browser.sleep(timeout);

EC = protractor.ExpectedConditions;

browser.wait(EC.not(EC.visibilityOf(loader)), 80000); // not / and / or

browser.wait(EC.visibilityOf(menu), timeout);

browser.wait(EC.invisibilityOf(loader), timeout);

Page 21: Protractor framework – how to make stable e2e tests for Angular applications

Testing different modules

4

Page 22: Protractor framework – how to make stable e2e tests for Angular applications

Browser.ignoreSynchronization

or

Testing non-angular modules

Page 23: Protractor framework – how to make stable e2e tests for Angular applications

Window handles, testing Share/Follow buttons

afterEach(() => browser.ignoreSynchronization = false);

it('Check twitter', () => { MatrixPage.hamburgerMenu.click(); MatrixPage.getShareButtonInHamburgerMenu('twitter').click().then(() => { browser.getAllWindowHandles().then((handles: any) => { browser.ignoreSynchronization = true; browser.switchTo().window(handles[1]).then(() => { expect(browser.getCurrentUrl()).toContain('Some URL'); expect(SharePages.inputFieldTwitter.getText()).toContain('Some text and link'); }); browser.switchTo().window(handles[0]); }); });});

Page 24: Protractor framework – how to make stable e2e tests for Angular applications

Supporting

5

Page 25: Protractor framework – how to make stable e2e tests for Angular applications

Main reasons of failed tests

Selectors

Waits for loading elements

Incorrect configuration

Lobster

Failures Protractor framework

Page 26: Protractor framework – how to make stable e2e tests for Angular applications

How to hold of the browser's console?

browser.manage().logs().get('browser').then((browserLog) => { console.log('log: ' + require('util').inspect(browserLog));});

Page 27: Protractor framework – how to make stable e2e tests for Angular applications

Screenshots with Protractordescribe('Take screenShot', () => { using(DataProvider.allUrls, (data: any, description: string) => { it('from page' + description, () => { browser.get(data.url); const writeScreenShot = (info: any, filename: string) => { let stream = fs.createWriteStream(filename); stream.write(new Buffer(info, 'base64')); stream.end(); }; browser.takeScreenshot().then((png: any) => { writeScreenShot(png, description + '.png'); }); }); });});

Page 28: Protractor framework – how to make stable e2e tests for Angular applications

Make screenshot for failures

jasmine.getEnv().addReporter(() => { this.specDone = (result: any) => { if (result.failedExpectations.length > 0) { takeScreenShot(); } };});

Page 29: Protractor framework – how to make stable e2e tests for Angular applications

Tips & Tricks

Page 30: Protractor framework – how to make stable e2e tests for Angular applications

Protractor + Page Object

Main Page

Login Page

Abstract Page

Test

beforeAll : Login

test: Main Page

using: Abstract Page

Page 31: Protractor framework – how to make stable e2e tests for Angular applications

export class AbstractPage { public static getEC(): ProtractorExpectedConditions { return protractor.ExpectedConditions; }; public static sendQuery(field: ElementFinder, query: string): any { field.clear().then(() => field.sendKeys(query)); };}

Abstract Page

Login Page

export class LoginPage { public static emailInput: ElementFinder = element(by.id('JobSeekerLogin')); public static passwordInput: ElementFinder = element(by.id('JobSeeker')); public static loginButton: ElementFinder = element(by.id('signin')); public static redirectWindow: ElementFinder = $('.inner-g');

public static login(): any { browser.get('/'); browser.wait(AbstractPage.getEC().inVisibilityOf(this.redirectWindow)), 9000); AbstractPage.sendQuery(this.emailInput, '[email protected]'); AbstractPage.sendQuery(this.passwordInput, 'testPass'); this.loginButton.click();};}

Page 32: Protractor framework – how to make stable e2e tests for Angular applications

Test

describe('Main page ', () => { beforeAll(() => { LoginPage.login(); });

it('check visibility of elements ', () => { expect(MainPage.personifiedDropDown.isDisplayed()).toBe(false); expect(MainPage.filtersH3.getText()).toEqual('Test String H3'); expect(MainPage.searchButton.isPresent()).toBeTruthy(); });});

Page 33: Protractor framework – how to make stable e2e tests for Angular applications

Protractor + Page Object + Data Provider

Main Page

Login Page

Abstract Page

Test

beforeAll : Login

test: Main Page

using: Abstract Page

DataProvider

Page 34: Protractor framework – how to make stable e2e tests for Angular applications

Test

export class DataProvider { public static mainPageBoolean: any = { 'Logo': {element: (): ElementFinder => $('img[src*="Logo."]')}, 'LogOut Button': {element: (): ElementFinder => element(by.id('sign-out-link'))}, 'All Products button': {element: (): ElementFinder => $('a[class*="shopping"]')}, 'Input for keywords': {element: (): ElementFinder => $('input[class*="keyword"]')} };}

const using = require('jasmine-data-provider');describe('Main page ', () => { using(DataProvider.mainPageBoolean, (data: any, description: string) => { it('check visibility of: ' + description, () => { expect(data.element().isDisplayed()).toBe(true); }); });

DataProvider

Page 35: Protractor framework – how to make stable e2e tests for Angular applications

Checking web-UI data after XLS parsing. -xlsjs- + Protractor

const xlsJs = require('xlsjs');

export class XLS { public static getDataFromXLS(cellId: string): string { let fileNamePath = './example.xls'; let workbook = xlsJs.readFile(fileNamePath); let sheetNumberlist = workbook.SheetNames; return workbook.Sheets[sheetNumberlist['1']][cellId].v; };}

Page 36: Protractor framework – how to make stable e2e tests for Angular applications

Checking web-UI data after XLS parsing. -xlsjs- + Protractor

const using = require('jasmine-data-provider');const colEn: string = 'A';

describe('Checking countries in language: ', () => { using(DataProvider.countyPageId, (data: any, description: string) => { it('English, country: ' + description, () => { browser.get('country/en' + data.countryId); expect(CountryPage.countryName.getText()).toEqual(description); expect(CountryPage.countryName.getText())

.toEqual(XLS.getDataFromXLS(colEn + data.numberOfCell)); }); });});

Page 37: Protractor framework – how to make stable e2e tests for Angular applications

Tests for drag&drop checking import { browser, protractor } from 'protractor';import { DropMePage } from '../pages/dropMePage';const dropFile = require('../helpers/dragAndDrop');let EC = protractor.ExpectedConditions;

describe('Drag and Drop Tests: ', () => { beforeAll(() => { browser.ignoreSynchronization = true; browser.get('https://dropfile.to/'); }); it('move files to service and check link as a result', () => { dropFile(DropMePage.inputFieldForImages, 'e2e/data/3.jpg'); DropMePage.startUploadingButton.click(); browser.wait(EC.visibilityOf(DropMePage.urlLoadedImage), 20000); expect(DropMePage.urlLoadedImage.getText()).toContain('https://dropfile.to/'); });});

Page 38: Protractor framework – how to make stable e2e tests for Angular applications

A few lines of code = many different testsusing(DataProvider.searchKeywordsQuery, (data: any, query: string) => { it('check suggestions in search field by keywords: ' + query, () => { AbstractPage.sendQuery(MainPage.inputKeyword, query); expect(MainPage.suggestionsKeywordsField.count())

.toBe(data.quantitySuggestions);

MainPage.suggestionsKeywordsField.each((suggestion: any) => {

expect(suggestion.isDisplayed()).toBeTruthy(); }); });});

1 it

2 expect

20 tests

11 checks in each test==>

Page 39: Protractor framework – how to make stable e2e tests for Angular applications

Questions?http://www.protractortest.org/

https://github.com/angular/protractor

https://github.com/angular/protractor/blob/master/CHANGELOG.md

https://github.com/ludmilanesvitiy/ProtractorExample

https://github.com/ludmilanesvitiyhttps://ua.linkedin.com/in/[email protected]