Skip to main content
Version: 3.0.1

Selenium IDE Test Guide

Purpose and Audience

This guide documents how to create and maintain browser automation tests using the Selenium IDE 2.0 JSON format (.side files) for the PCR Analysis system. These are end-to-end UI tests that validate application behavior through browser interaction, typically targeting the pre-production environment.

Audience: Developers and QA Engineers responsible for writing, maintaining, or reviewing browser-based automated tests.

Tests are stored as .side files in the exports/ghostinspector/ directory of the test repository. The format is compatible with both Selenium IDE and Ghost Inspector import/export.

See the Testing Guide for Behat/Cucumber test writing.


File Format

Selenium IDE 2.0 JSON format (.side extension).


Root Structure

{
"id": "uuid",
"version": "2.0",
"name": "Project Name",
"url": "",
"urls": [],
"tests": [
// Array of test objects
]
}
FieldTypeDescription
idstringUUID for the project
versionstringAlways "2.0"
namestringProject/suite name
urlstringDefault base URL (can be empty if using variables)
urlsarrayAdditional URLs (usually empty)
testsarrayArray of test objects

Test Object Structure

{
"id": "uuid",
"name": "Test Name",
"commands": [
// Array of command objects
]
}
FieldTypeDescription
idstringUUID for the test
namestringTest name
commandsarrayArray of command objects

Command Object Structure

{
"id": "uuid",
"comment": "Description of command",
"command": "selenium_command",
"target": "selector or value",
"targets": [],
"value": "parameter value"
}
FieldTypeDescription
idstringUUID for the command
commentstringDescription/comment for the command
commandstringSelenium IDE command name
targetstringPrimary target (selector, URL, value)
targetsarrayAlternative targets (usually empty)
valuestringSecondary value/parameter

Common Commands Reference

{"command": "open", "target": "${URL_root}/login/admin", "value": ""}
{"command": "setWindowSize", "target": "1280x800", "value": ""}

Variables

{"command": "store", "target": "username_value", "value": "username"}
{"command": "store", "target": "password_value", "value": "password"}

Input

{"command": "type", "target": "xpath=//input[@id=\"username-field\"]", "value": "${username}"}
{"command": "sendKeys", "target": "css=input", "value": "${variable}"}

Clicks

{"command": "click", "target": "css=button[type=\"submit\"]", "value": ""}
{"command": "click", "target": "xpath=//button[.//span[text()=\"Apply\"]]", "value": ""}

Waits/Pauses

{"command": "pause", "target": "2000", "value": ""}

Assertions

{"command": "assertElementPresent", "target": "css=#token", "value": ""}
{"command": "assert", "target": "checkReturnValue", "value": "true"}

JavaScript Execution

{"command": "executeScript", "target": "return window.location.href", "value": "mfa_link"}
{"command": "executeScript", "target": "const element = document.querySelector('#token');\nreturn element.textContent;", "value": "totp"}

Conditional Logic

{"command": "if", "target": "!!${checkConditionalValue}", "value": ""}
{"command": "end", "target": "", "value": ""}

Selector Types

CSS Selectors

css=button[type="submit"]
css=#token
css=input[placeholder="The secret key"]

XPath Selectors

xpath=//input[@id="username-field"]
xpath=//button[.//span[text()="Apply"]]
xpath=//div[contains(@class, "filter-name") and normalize-space(text())="Actions"]
xpath=//div[@title="LJ Report"]

Variable Usage

Variables are stored with the store command and referenced with ${variable_name}:

// Store a variable
{"command": "store", "target": "admin_user", "value": "username"}

// Use the variable
{"command": "type", "target": "xpath=//input[@id=\"username-field\"]", "value": "${username}"}

Common Variables

VariableDescription
${URL_root}Base URL for the environment
${username}Login username
${password}Login password
${hotp}TOTP secret key
${totp}Generated TOTP code
${mfa_link}MFA redirect URL

Authentication Flow Template

The tests use TOTP-based MFA authentication. Below is the standard login flow used across all test suites:

[
{"comment": "Open login page", "command": "open", "target": "${URL_root}/login/admin"},
{"comment": "Set window size", "command": "setWindowSize", "target": "1280x800"},
{"comment": "Store username", "command": "store", "target": "username_value", "value": "username"},
{"comment": "Store password", "command": "store", "target": "password_value", "value": "password"},
{"comment": "Store TOTP secret", "command": "store", "target": "TOTP_SECRET_HERE", "value": "hotp"},
{"comment": "Enter username", "command": "type", "target": "xpath=//input[@id=\"username-field\"]", "value": "${username}"},
{"comment": "Enter password", "command": "type", "target": "xpath=//input[@id=\"password-field\"]", "value": "${password}"},
{"comment": "Click submit", "command": "click", "target": "css=button[type=\"submit\"]"},
{"comment": "Capture MFA redirect URL", "command": "executeScript", "target": "return window.location.href", "value": "mfa_link"},
{"comment": "Go to TOTP generator", "command": "open", "target": "https://totp.danhersam.com/"},
{"comment": "Enter TOTP secret", "command": "type", "target": "css=input[placeholder=\"The secret key (in base-32 format)\"]", "value": "${hotp}"},
{"comment": "Wait for TOTP generation", "command": "pause", "target": "3000"},
{"comment": "Wait for token element", "command": "assertElementPresent", "target": "css=#token"},
{"comment": "Capture TOTP code", "command": "executeScript", "target": "const element = document.querySelector('#token');\nreturn element.textContent;", "value": "totp"},
{"comment": "Return to app", "command": "open", "target": "${mfa_link}"},
{"comment": "Enter TOTP code", "command": "type", "target": "xpath=//input[@name=\"totp_code\"]", "value": "${totp}"},
{"comment": "Submit MFA", "command": "click", "target": "css=button[type=\"submit\"]"}
]

Complete Test Template

{
"id": "test-uuid-here",
"name": "Test Name",
"commands": [
{
"id": "cmd-1-uuid",
"comment": "Open start URL",
"command": "open",
"target": "${URL_root}/page",
"targets": [],
"value": ""
},
{
"id": "cmd-2-uuid",
"comment": "Set window size",
"command": "setWindowSize",
"target": "1280x800",
"targets": [],
"value": ""
},
{
"id": "cmd-3-uuid",
"comment": "Click element",
"command": "click",
"target": "xpath=//button[@id=\"action-button\"]",
"targets": [],
"value": ""
},
{
"id": "cmd-4-uuid",
"comment": "Wait for result",
"command": "pause",
"target": "2000",
"targets": [],
"value": ""
},
{
"id": "cmd-5-uuid",
"comment": "Verify element present",
"command": "assertElementPresent",
"target": "xpath=//div[@class=\"success-message\"]",
"targets": [],
"value": ""
}
]
}

Complete Project Template

{
"id": "project-uuid-here",
"version": "2.0",
"name": "Project Name",
"url": "",
"urls": [],
"tests": [
{
"id": "test-1-uuid",
"name": "Test Case 1",
"commands": [
// Commands here
]
},
{
"id": "test-2-uuid",
"name": "Test Case 2",
"commands": [
// Commands here
]
}
]
}

Existing Tests

The current project includes 12 Selenium IDE tests (exported from Ghost Inspector):

Test NamePurpose
AuditTest audit functionality
LJ ReportTest Levey-Jennings report
Outcomes ReportTest outcomes report generation
Runfile ListTest runfile list pagination
Runfile ReportTest runfile report
Runfile Report (Assay Summary)Test assay summary view
Runfile Report (Outcome Summary)Test outcome summary view
Runfile Report (Plate Map)Test plate map visualization
Runfile Report (Quantification)Test quantification data
Runfile Report (Westgards)Test Westgard rules display
Trends ReportTest trends analysis
Upload RunsTest run file upload

Best Practices

  1. Use descriptive comments -- Every command should have a clear comment explaining its purpose.
  2. Use variables for credentials -- Never hardcode passwords in commands.
  3. Add waits appropriately -- Use pause or assertElementPresent before interactions with dynamically loaded elements.
  4. Use stable selectors -- Prefer IDs and data attributes over class names, which are more likely to change.
  5. Generate unique UUIDs -- Each project, test, and command needs a unique ID.
  6. Test in isolation -- Each test should handle its own setup (login, navigation) without depending on state from other tests.
  7. Use XPath for complex selectors -- When CSS selectors are insufficient for targeting specific elements.