Yauhen Kavaliou Andrei Palchys “We don’t need QA anymore” or Protractor
Sencha Touch 2 Cordova 5+ products (phone/tablet & ios/android) +3 years and 150k LoC Project
2 small teams 7 developers 5 manual QA 4 automation testers Team
Many changes every release Developers produces more code than QA (Manual and Auto) can test in 2 week sprint. There is a misbalance in maturity between Devs and QA
Experiment One dev team will develop and cover features with automation tests Automation tests will be written based on QA tests cases.
Selenium WebDriver
TestWebDriverBrowser API
JSON wire protocol POST /session/ /url { "url" : " }
ChromeDriver FirefoxDriver InternetExplorerDriver SafariDriver GhostDriver
Appium
Protractor is an end-to-end test framework for AngularJS JavaScript applications.
describe('rollingscopes.com', function () { it('check meetup name', function () { browser.get(' var text = element(by.css('.banner h1')).getText(); expect(text).toEqual('The Rolling Scopes #19'); }); Protractor provides nice abstraction on top of WebDriver API and uses Jasmine as a test framework
The WebDriver Control Flow var text = element(by.css('.banner h1')).getText(); expect(text).toEqual('The Rolling Scopes #19'); You write async code in sync way
Google Chrome and ChromeDriver
Jasmine Suits and Specs
describe( 'Suit Name', function(){ /*specs*/ }) it( 'Spec Name', function(){ /*expect*/ }, timeout) expect(a).toBe(b).not.toBe(b).toBeGreaterThan(b).toBeLessThan(b).toEqual(b).toBeDefined().toMatch(/\d+/g) …
Approaches - “Smart” automated tests - User as a config
{ login: 'user', password: 'password', preferences: { hasAccessToFeatures: false, isAdmin: true, hasAnalytics: false }, navigation: [ 'home', ‘settings' ] }
var specs = { setup: './Base/spec/Setup.js', … complete: './Base/spec/Complete.js' }; module.exports = { specs: specs, mandatory: [specs.setup, specs.login], full: [ specs.setup, { name: specs.home, allowed: '*', disabled: ['multipleDeals'] }, specs.settings, specs.complete ] }
Page Object
Before describe(‘angularjs homepage', function() { it('should greet the named user', function() { browser.get(' element(by.model('yourName')).sendKeys('Julie'); var greeting = element(by.binding('yourName')); expect(greeting.getText()).toEqual('Hello Julie!'); });
After describe('angularjs homepage', function() { it('should greet the named user', function() { var angularHomepage = new AngularHomepage(); angularHomepage.get(); angularHomepage.setName('Julie'); expect(angularHomepage.getGreeting()).toEqual('Hello Julie!');
Promises
Base components views util spec Project1 components config spec views Project2 components config spec views
browser.executeScript(string|Function, args) browser.executeScriptAsync(string|Function, args)
Utils - WaitFor method based on ExpectedConditions -Touch interactions and scrolling based on mouseEvents и scriptExecute - Specific methods for Sencha Touch, for example - scroll to selected Record and e.t.c.
var EC = protractor.ExpectedConditions; exports.waitFor = function (selector, time) { return browser.wait(EC.presenceOf(element(by.css(selector))), time || 10000); } exports.waitForVisibility = function (selector, time) { return browser.wait(EC.visibilityOf(element(by.css(selector))), time || 10000); } exports.waitForHidden = function (selector, time) { return browser.wait(EC.invisibilityOf(element(by.css(selector))), time || 10000); }}
11:06: INFO - Executing: [find elements: By.cssSelector:.main-container]) 11:06: INFO - Done: [find elements: By.cssSelector:.main-container] 11:06: INFO - Executing: [is enabled: 17 [[ChromeDriver: chrome on XP (fb89e8300a09af71aa37b0b5041c8052)] -> css selector:.main-container]]) 11:06: INFO - Done: [is enabled: 17 [[ChromeDriver: chrome on XP (fb89e8300a09af71aa37b0b5041c8052)] -> css selector:.main-container]]... it('App is ready', function() { //Util.waitFor(this.CSS.container) mainView.waitForLoading(); //browser.isElementPresent(by.css(this.CSS.container)) expect(mainView.isPresent()).toBe(true); });...
xtype support by.xtype = function (xtype) { return { findElementsOverride: function (driver, using, rootSelector) { return driver.findElements( by.xpath( + xtype + '")] | + xtype + '")]' ), rootSelector); }, toString: function toString() { return 'by.xtype("' + xtype + '")'; } };
Timeouts { allScriptTimeout : timeout } browser.manage().timeouts().implicitlyWait(timeout) jasmineNodeOpts.defaultTimeoutInterval = timeout it ('Spec Name', function(){ /*expect*/ }, timeout)
browser.sleep(timeout)
Plugins - Screenshot reporter - Console - Report …
Issues -Different speed of executing on different environments - Tough to debug - Why did my test fail? -WebDriver crashes -DOM manipulations in real-time - Invisible items
Debug Node-inspector
Conclusions