Skip to content

Instantly share code, notes, and snippets.

Created January 26, 2018 17:51
Show Gist options
  • Save Maggers/63fbbc7af1d9a1883d545ed08febefd6 to your computer and use it in GitHub Desktop.
Save Maggers/63fbbc7af1d9a1883d545ed08febefd6 to your computer and use it in GitHub Desktop.
Sample file for the Automated Testing article
// Testing file for TodoMVC within Automated Testing article
// Jason McConnell 2017
var webdriver = require('selenium-webdriver');
var expect = require('chai').expect;
var path = require('path');
describe('Run four tests against TODOMVC sample', function () {
process.env.path = `${process.env.path};${__dirname};`; //eslint-disable-line no-process-env
var capabilities = {
'browserName': 'MicrosoftEdge',
'browserstack.user': 'YOURUSERNAME',
'browserstack.key': 'YOURBROWSERSTACKKEY',
'browserstack.debug': 'true',
'build': 'BrowserStack Automate'
var entrytoEdit = "Browser Stare";
var toDoTestItems = [entrytoEdit, "Learn Chai", "Integrate Mocha"];
var browser = new webdriver.Builder().
// uncomment this next line to use BrowserStack with your crendentials and comment-out usingServer().:
before(async () => {
// Have the browser navigate to the TODO MVC example for React
await browser.get('');
//await browser.get('');
//Send a wait to the browser to account for script execution running
await browser.manage().timeouts().implicitlyWait(1000);
//1. Enter 3 new ToDo items and check that they were successfully added to the list
//Find the input field on the page and assign it to todoEntry
//Use the Async await pattern to query values from Webdriver more elegantly
const todoEntry = await browser.findElement(webdriver.By.css('.new-todo'));
//Send keystrokes to the field we just found with the test strings and then send the Enter special character
for (const item of toDoTestItems) {
await todoEntry.sendKeys(item);
await todoEntry.sendKeys("\n");
// const title = await browser.getTitle();
// console.log(title);
describe('Initial tests', () => {
it('TEST 1: Query the page for TODO items and test they match what was sent', async () => {
//We look for the test values we entered in the TODO list by getting a collection of webelements
//We use WebDrivers CSS pattern matching strategy. Items in the list have CSS properties todo-list and label
const testElements = await browser.findElements(webdriver.By.css('.todo-list label'));
console.log('Found', testElements.length, 'ToDo items.');
//Test that the collection contains elements and then iterate through them checking the values match what we sent the page
//You could do string comparison operations on each of these but using Chai we can write simple tests
//Chai allows us to use assertions to describe the expected value or behaviour within JS.
//The test itself we will execute using a test runner that works with Node. It's called Mocha
//Both Chai and Mocha are installed using NPM.
//test that testElements is non-zero
//make sure that we're comparing the right number of items in each array/collection
//iterate through the collection and make sure the text entered matches what's now in the list
for (let i = 0; i < testElements.length; i++) {
const text = await testElements[i].getText();
//2. Modify an item by double clicking and changing text in the item
//TODO: make the number of backspace presses a variable and loop through to send the backspaces
it('TEST 2: Edit a TODO and validate it matches what was typed', async () => {
const testElements = await browser.findElements(webdriver.By.css('.todo-list label'));
var newText = "ack";
var numBackSpaces = 3;
var modifiedText = entrytoEdit.slice(0, entrytoEdit.length - numBackSpaces) + newText;
// Move the mouse pointer to the first element in the TODO list
await browser.actions().mouseMove(testElements[0]).perform();
await browser.actions().doubleClick().perform();
// The React application will create a new input class="edit" for the item we double clicked on
// Get the new editable item so we can send keys to it
const editableItem = await browser.findElement(webdriver.By.css('.todo-list input.edit'));
for (let i = 0; i < numBackSpaces; i++) {
await editableItem.sendKeys('\b');
await editableItem.sendKeys(newText);
await editableItem.sendKeys('\n');
//The items have changed in the list so we need to refresh our collection
const updatedItems = await browser.findElements(webdriver.By.css('.todo-list label'));
const newFirstItem = await updatedItems[0].getText();
//Check that the edited item in the list matches what we typed via WebDriver
//3. Delete the current item
it('TEST 3: Delete a TODO item from the list by clicking the X button', async () => {
const updatedItems = await browser.findElements(webdriver.By.css('.todo-list label'));
// The React TODOMVC example uses a button with class "destroy" to delete items from the list
const destroyButtons = await browser.findElements(webdriver.By.css('.todo-list .destroy'));
console.log("Found " + destroyButtons.length + " destroy class items");
await browser.actions().mouseMove(destroyButtons[0]).perform();
//now send a mouse click to delete the item
await browser.actions().click().perform();
//get the items again and see that there is one less item
const updatedItemsPostDelete = await browser.findElements(webdriver.By.css('.todo-list label'));
expect(updatedItemsPostDelete.length).to.equal(updatedItems.length - 1);
//4. Check an item as completed
it('TEST 4: Mark an item as complete and test the number of items has reduced by 1', async () => {
//First, find the # of items left in the list as shown in the footer of the TODO list.
//we'll compare this value post the check box click to make sure it's reduced by 1
const itemsLeft = await browser.findElement(webdriver.By.css('.todo-count strong'));
const countItemsLeft = await itemsLeft.getText();
console.log("Currently there are " + countItemsLeft + " items left");
//Let's get a list of input checkboxes with class 'toggle'.
const toggleCheckBoxes = await browser.findElements(webdriver.By.css('.todo-list .toggle'));
console.log("found " + toggleCheckBoxes.length + " check boxes");
//let's send a mouse click to the first check box in the collection to mark it completed
await browser.actions().mouseMove(toggleCheckBoxes[0]).perform();
//now send a mouse click to mark the item as checked off
await browser.actions().click().perform();
// The item should now be marked as complete and the todo-count should be reduced by one.
// let's compare the current todo-count with the value we retrieved earlier and test
const currentItemsLeft = await browser.findElement(webdriver.By.css('.todo-count strong'));
const countCurrentItemsLeft = await currentItemsLeft.getText();
expect(parseInt(countCurrentItemsLeft)).to.equal((parseInt(countItemsLeft)) - 1);
//End the browser session to avoid timeouts
await browser.quit();
Copy link

zedwang commented Feb 5, 2018

Hi,Maggers.What is the version NO of selenium-webdriver?

Copy link

sericaia commented Feb 28, 2018

Can we use after to do browser.quit();, its a bit messy to have it in the last test. Other than that, its a nice explanation ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment