20. Appendix 3a: JavaScript, Python & Scriptworks multi-language Test Activity example

The popular <https://www.Saucedemo.com> site is a shopping app that many Test Automation demos target. Here we show how Vitaq AI powered by Scriptworks can test all user journeys with just 15 shared Test Action scripts. We even use a Python script to read and write to a spreadsheet to check that the prices in the shopping app are correct against the oracle golden reference pricesheet.

_images/30_mixed_test_activity.png

20.1. JSFunctions File

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
async function getItemPrice() {
    await driver.wait(until.elementLocated(By.xpath('//div[@class="inventory_details_price"]')), 1000, 'Could not find Backpack element within the time specified');
    const price = await driver.findElement(By.xpath('//div[@class="inventory_details_price"]')).getText();
    console.log(price)
    await driver.wait(until.elementLocated(By.xpath('//div[@class="inventory_details_name"]')), 1000, 'Could not find Backpack element within the time specified');
    const name = await driver.findElement(By.xpath('//div[@class="inventory_details_name"]')).getText();
    console.log(name)
    await sendDataToVitaq("item_price", price);
    await sendDataToVitaq("item_description", name);
}

20.2. setUp

1
2
3
4
async function setUp() {
    console.log('Running Test Action SetUp');
    await driver.get('https://www.saucedemo.com');
}

20.3. logIn

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
async function logIn() {
    
    const acceptedUserNames = await requestData('acceptedUserNames');
    await driver.findElement(By.id('user-name')).sendKeys(acceptedUserNames);
    const passwordForAllUsers = await requestData('passwordForAllUsers');
    await driver.findElement(By.id('password')).sendKeys(passwordForAllUsers);
    await driver.findElement(By.className('btn_action')).click();
    const currentURL = await driver.getCurrentUrl();
    console.log('URL is:  ' + currentURL);
    expect(currentURL).equals('https://www.saucedemo.com/inventory.html');
    
    // Record coverage for these Test Activity Variables in the login Action
    
    await recordCoverage("",`acceptedUserNames`);
    await recordCoverage("",`passwordForAllUsers`);
}

20.4. Products

1
2
3
async function Products(){
    console.log("Running Test Action Script Products");
}

20.5. Back

1
2
3
4
async function Back(){
    console.log("Running Test Action Script Back");
    await driver.findElement(By.xpath(`//*[normalize-space(text())="<- Back"]`)).click();
}

20.6. logOut

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
async function logOut() {
    await driver.wait(until.elementLocated(By.xpath(`//*[normalize-space(text())="Open Menu"]`)), 1000, 'Could not find the Open menu element to be present');
    await driver.findElement(By.xpath(`//*[normalize-space(text())="Open Menu"]`)).click();
    
    console.log("Disabling return actions to enable logOut user journey from exhaustive sequence");
    
    await runCommand(`set_enabled`,`Backpack, False`);
    await runCommand(`set_enabled`,`Onesie, False`);
    await runCommand(`set_enabled`,`Bikelight, False`);
    await runCommand(`set_enabled`,`tshirt_red, False`);
    await runCommand(`set_enabled`,`tshirt_bolt, False`);
    await runCommand(`set_enabled`,`Fleece, False`);
    await runCommand(`set_enabled`,`sortItems, False`);
}

20.7. sortItems

1
2
3
4
5
6
7
8
9
async function sortItems(){
    console.log('Running Test Action Script sortItems');
    await driver.wait(until.elementLocated(By.xpath('//*[@class="product_sort_container"]')), 1000, 'Could not find product sort element with the time specified');
    await driver.findElement(By.xpath('//*[@class="product_sort_container"]')).sendKeys(await requestData('sortOrder'));
    
    // Record coverage for sortOrder
    await recordCoverage("",`sortOrder`);
    
}

20.8. backpack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
async function Backpack() {
    console.log('Running Test Action for Backpack');
    // await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Sauce Labs Backpack"]')), 1000, 'Could not find Backpack element within the time specified');
    // await driver.findElement(By.xpath('//*[normalize-space(text())="Sauce Labs Backpack"]')).click();
    
    //div[contains(text(),'Sauce Labs Backpack')]
    await driver.wait(until.elementLocated(By.xpath('//div[contains(text(),"Sauce Labs Backpack")]')), 1000, 'Could not find Backpack element within the time specified');
    await driver.findElement(By.xpath('//div[contains(text(),"Sauce Labs Backpack")]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.9. Onesie

1
2
3
4
5
6
7
8
async function Onesie() {
    console.log('Running Test Action for Onesie');
    await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Sauce Labs Onesie"]')), 1000, 'Could not find Onesie element within the time specified');
    await driver.findElement(By.xpath('//*[normalize-space(text())="Sauce Labs Onesie"]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.10. Bikelight

1
2
3
4
5
6
7
8
async function Bikelight() {
    console.log('Running Test Action for Bikelight');
    await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Sauce Labs Bike Light"]')), 1000, 'Could not find Bikelight element within the time specified');
    await driver.findElement(By.xpath('//*[normalize-space(text())="Sauce Labs Bike Light"]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.11. tshirt_red

1
2
3
4
5
6
7
8
async function tshirt_red() {
    console.log('Running Test Action for tshirt_red');
    await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Test.allTheThings() T-Shirt (Red)"]')), 1000, 'Could not find tshirt-red element within the time specified');
    await driver.findElement(By.xpath('//*[normalize-space(text())="Test.allTheThings() T-Shirt (Red)"]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.12. tshirt_bolt

1
2
3
4
5
6
7
8
async function tshirt_bolt() {
    console.log('Running Test Action for tshirt_bolt');
    await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Sauce Labs Bolt T-Shirt"]')), 1000, 'Could not find tshirt-bolt element within the time specified');
    await driver.findElement(By.xpath('//*[normalize-space(text())="Sauce Labs Bolt T-Shirt"]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.13. Fleece

1
2
3
4
5
6
7
8
async function Fleece() {
    console.log('Running Test Action for Fleece');
    await driver.wait(until.elementLocated(By.xpath('//*[normalize-space(text())="Sauce Labs Fleece Jacket"]')), 1000, 'Could not find Fleece element within the time specified');
    await driver.findElement(By.xpath('//*[normalize-space(text())="Sauce Labs Fleece Jacket"]')).click();
    
    // Get the price for this item
    getItemPrice()
}

20.14. CheckPrice

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
print("The recorded item price is: {}".format(self.parent.item_price))

# Open the work book and set the sheet
self.parent.workbook = xw.Book("./price_list.xlsx")
prices_sheet = self.parent.workbook.sheets['Sheet1']

# Define the columns to use, start row etc.
description_column = 'B'
prices_column = 'C'
start_row = 2
num_rows = 7
current_row = start_row

# Iterate through xls looking for description and then read price
found_price = False
while not found_price:
    description_cell = '{}{}'.format(description_column, current_row);
    price_cell = '{}{}'.format(prices_column, current_row);
    if prices_sheet.range(description_cell).value == self.parent.item_description:
        list_price = prices_sheet.range(price_cell).value
        found_price = True
    current_row += 1

print("List price is: ", list_price);
    
# Remove the pound symbol from the price derived from the webpage and convert to float
# Treats string as array and removes frist character
item_price = float(self.parent.item_price[1:])
  
if list_price == item_price:
    print("The price is correct")
    return True
else:
    print("ERROR: The price is incorrect")
    return False

20.15. ShoppingCart

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
async function ShoppingCart() {
    console.log('Running Test Action Script ShoppingCart');
    
    let cartAction = driver.findElement(By.xpath(`//*[normalize-space(text())="ADD TO CART" or normalize-space(text())="REMOVE"]`));
    
    let addRemove = await cartAction.getText();
    
    console.log('The product is ready to ', addRemove);
    
    if (String(addRemove) === `ADD TO CART`) {
        await driver.findElement(By.xpath(`//*[normalize-space(text())="ADD TO CART"]`)).click();
    }
    if (String(addRemove) === `REMOVE`) {
        await driver.findElement(By.xpath(`//*[normalize-space(text())="REMOVE"]`)).click();
    }
    
    console.log('Moving onto Shopping cart');
    // await driver.wait(until.elementLocated(`//*[@class="svg-inline--fa fa-shopping-cart fa-w-18 fa-3x"]`), 10000, 'Could not find the shopping cart element within the time specified');
    // await driver.findElement(By.xpath(`//*[@class="svg-inline--fa fa-shopping-cart fa-w-18 fa-3x"]`)).click();
    await driver.findElement(By.xpath(`//*[@class="svg-inline--fa fa-shopping-cart fa-w-18 fa-3x "]`)).click();
}

20.16. ContinueShopping

1
2
3
4
5
async function ContinueShopping(){
    console.log("Running Test Action Script for ContinueShopping");
    await driver.wait(until.elementLocated(By.xpath(`//*[@class="btn_secondary"]`)), 1000, 'Could not find the continue shopping element within the time specified');
    await driver.findElement(By.xpath(`//*[@class="btn_secondary"]`)).click();
}

20.17. tearDown

1
2
3
async function tearDown() {
    console.log("Running test action script tearDown");
}