cucumber-browser-preset-myob v0.0.10
cucumber-browser-preset-myob
A Node library intended to simplify browser based automation.
Motivation
At MYOB we develop a number of frontend's using a similar browser automation toolsets and patterns.
We found the process for replicating, upgrading & sustaining these tools was onerous as the numbers of frontend's fanned-out.
This library strives to simplify this effort.
Dependencies
This library integrates tightly with the following libraries:
- Cucumber
- Selenium
- geckodriver to drive Firefox
- chromedriver to drive Google Chrome
Patterns & Practices
The library encourages UI automation patterns & practices:
- Use of Page Objects
- Use of Flow Objects, an extension to Page Objects, capturing common flows of activity through a UI
- Stubbing backend integration using http_stub, giving you full control over backend data and availability
- Takes a browser screenshot on any failure, writing an image to disk
- Reduces the browsers size when configured to simulate a mobile screen size
Usage
The projects features directory is a usage example. The project offers a number of integration points.
Test Runner
A cucumber_browser_runner
sh script is provided that runs cucumber using babel and auto-loads essential cucumber-browser-preset-myob
dependencies.
The browser can be selected using the BROWSER_TYPE
environment variable. Currently supported browsers are:
- firefox (default)
- chrome
Page Objects
A base Page class provides short-hand for interacting with elements on page. To use a Page Object, extend the base class, register the class and then find and use the page when needed:
// pages/MyPage.js
import { Page } from 'cucumber-browser-preset-myob';
export default class MyPage extends Page {
// Define location of elements referred to on page
elementLocators = {
someElement: { id: 'someElement' },
submit: { xpath: '\\input[type="submit"]' }
};
// Implement load if your page can be accessed directly
load() {
return this.browser.get('http://my.page');
}
// Provide some way of determining the page is loaded (mandatory)
waitUntilVisible() {
return this.findVisibleElement('someElement');
}
// Interact with elements of page as needed
submit() {
return this.findVisibleElement('submit');
}
}
// support/world.js
import CucumberPresets from 'cucumber-browser-preset-myob';
import MyPage from '../pages/MyPage';
module.exports = CucumberPresets.createWorld(
(world) => {
// Pages must be registered for use
world.pageRegistry.register({ 'My Page', MyPage });
}
);
// step_definitions/my-steps.js
import World from '../support/World';
module.exports = function() {
this.World = World;
this.When(/^I submit My Page$/, function () {
// Pages can be found in the registry
this.page = this.pageRegistry.find('My Page');
return this.page.loadAndWaitUntilVisible().then(() => this.page.submit());
});
}
A set of page related step definitions are loaded by the test runner and available by default - see page-steps.js.
Flow Objects
A base Flow class aids navigation across pages. To use a Flow Object, the steps are identical to Page Objects:
// flows/MyFlow.js
import { Flow } from 'cucumber-browser-preset-myob';
export default class MyFlow extends Flow {
// Implements the steps of the flow (mandatory)
go() {
const myPage = this.pageRegistry.find('My Page');
return myPage.loadAndWaitUntilVisible().then(() => myPage.submit());
}
}
// support/world.js
import CucumberPresets from 'cucumber-browser-preset-myob';
import MyFlow from '../flows/MyFlow';
module.exports = CucumberPresets.createWorld(
(world) => {
// Pages must be registered for use
world.flowRegistry.register({ 'My Flow', MyFlow });
}
);
// step_definitions/my-steps.js
import World from '../support/World';
module.exports = function() {
this.World = World;
this.When(/^I have submitted data$/, function () {
// Flows can be found in the registry
return this.flowRegistry.find('My Flow').go();
});
}
http_stub Stubs
Through a stub registry you can register a stub as being available on a port and subsequently interact with the stub.
// support/world.js
import CucumberPresets from 'cucumber-browser-preset-myob';
module.exports = CucumberPresets.createWorld(
(world) => {
// Stubs running on a port are referenced by name
world.stubRegistry.register({ 'My Stub', 5000 });
}
);
// step_definitions/my-steps.js
import World from '../support/World';
module.exports = function() {
this.World = World;
this.When(/^I have submitted data$/, function () {
// Flows can be found in the registry
return this.stubRegistry.find('My Stub').activate('My Scenario');
});
}
World Generation
A cucumber World factory method is provided that provides the ability to use Page & Flow Objects as well as Stubs - see the examples above.