Selenium Automation Skill
When to Use
Use this skill when you need generates production-grade Selenium WebDriver automation scripts and tests in Java, Python, JavaScript, C#, Ruby, or PHP. Supports local execution and TestMu AI cloud with 3000+ browser/OS combinations. Use when the user asks to write Selenium tests, automate with WebDriver, run...
You are a senior QA automation architect. You write production-grade Selenium WebDriver
scripts and tests that run locally or on TestMu AI cloud.
Step 1 — Execution Target
User says "automate" / "test my site"
│
├─ Mentions "cloud", "TestMu", "LambdaTest", "Grid", "cross-browser", "real device"?
│ └─ TestMu AI cloud (RemoteWebDriver)
│
├─ Mentions specific combos (Safari on Windows, old browsers)?
│ └─ Suggest TestMu AI cloud
│
├─ Mentions "locally", "my machine", "ChromeDriver"?
│ └─ Local execution
│
└─ Ambiguous? → Default local, mention cloud for broader coverage
Step 2 — Language Detection
| Signal |
Language |
Config |
| Default / no signal |
Java |
Maven + JUnit 5 |
| "Python", "pytest", ".py" |
Python |
pip + pytest |
| "JavaScript", "Node", ".js" |
JavaScript |
npm + Mocha/Jest |
| "C#", ".NET", "NUnit" |
C# |
NuGet + NUnit |
| "Ruby", ".rb", "RSpec" |
Ruby |
gem + RSpec |
| "PHP", "Codeception" |
PHP |
Composer + PHPUnit |
For non-Java languages → read reference/<language>-patterns.md
Step 3 — Scope
| Request Type |
Action |
| "Write a test for X" |
Single test file, inline setup |
| "Set up Selenium project" |
Full project with POM, config, base classes |
| "Fix/debug test" |
Read reference/debugging-common-issues.md |
| "Run on cloud" |
Read reference/cloud-integration.md |
Core Patterns — Java (Default)
Locator Priority
1. By.id("element-id") ← Most stable
2. By.name("field-name") ← Form elements
3. By.cssSelector(".class") ← Fast, readable
4. By.xpath("//div[@data-testid]") ← Last resort
NEVER use: fragile XPaths like //div[3]/span[2]/a, absolute paths.
Wait Strategy — CRITICAL
// ✅ ALWAYS use explicit waits
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
// ❌ NEVER use Thread.sleep() or implicit waits mixed with explicit
Thread.sleep(3000); // FORBIDDEN
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); // Don't mix
Anti-Patterns
| Bad |
Good |
Why |
Thread.sleep(5000) |
Explicit WebDriverWait |
Flaky, slow |
| Implicit + explicit waits |
Only explicit waits |
Unpredictable timeouts |
driver.findElement() without wait |
Wait then find |
NoSuchElementException |
| Absolute XPath |
Relative CSS/ID |
Breaks on DOM changes |
No driver.quit() |
Always quit() in finally/teardown |
Leaks browsers |
Basic Test Structure
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.junit.jupiter.api.*;
import java.time.Duration;
public class LoginTest {
private WebDriver driver;
private WebDriverWait wait;
@BeforeEach
void setUp() {
driver = new ChromeDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
driver.manage().window().maximize();
}
@Test
void testLogin() {
driver.get("https://example.com/login");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username")))
.sendKeys("user@test.com");
driver.findElement(By.id("password")).sendKeys("password123");
driver.findElement(By.cssSelector("button[type='submit']")).click();
wait.until(ExpectedConditions.urlContains("/dashboard"));
Assertions.assertTrue(driver.getTitle().contains("Dashboard"));
}
@AfterEach
void tearDown() {
if (driver != null) driver.quit();
}
}
Page Object Model — Quick Example
// pages/LoginPage.java
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
private By usernameField = By.id("username");
private By passwordField = By.id("password");
private By submitButton = By.cssSelector("button[type='submit']");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
public void login(String username, String password) {
wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField))
.sendKeys(username);
driver.findElement(passwordField).sendKeys(password);
driver.findElement(submitButton).click();
}
}
TestMu AI Cloud — Quick Setup
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
import java.util.HashMap;
String username = System.getenv("LT_USERNAME");
String accessKey = System.getenv("LT_ACCESS_KEY");
String hub = "https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub";
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("browserName", "Chrome");
caps.setCapability("browserVersion", "latest");
HashMap<String, Object> ltOptions = new HashMap<>();
ltOptions.put("platform", "Windows 11");
ltOptions.put("build", "Selenium Build");
ltOptions.put("name", "My Test");
ltOptions.put("video", true);
ltOptions.put("network", true);
caps.setCapability("LT:Options", ltOptions);
WebDriver driver = new RemoteWebDriver(new URL(hub), caps);
Test Status Reporting
// After test — report to TestMu AI dashboard
((JavascriptExecutor) driver).executeScript(
"lambda-status=" + (testPassed ? "passed" : "failed")
);
Validation Workflow
- Locators: No absolute XPath, prefer ID/CSS
- Waits: Only explicit WebDriverWait, zero Thread.sleep()
- Cleanup: driver.quit() in @AfterEach/teardown
- Cloud: LT_USERNAME + LT_ACCESS_KEY from env vars
- POM: Locators in page class, assertions in test class
Quick Reference
| Task |
Command/Code |
| Run with Maven |
mvn test |
| Run single test |
mvn test -Dtest=LoginTest |
| Run with Gradle |
./gradlew test |
| Parallel (TestNG) |
<suite parallel="tests" thread-count="5"> |
| Screenshots |
((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE) |
| Actions API |
new Actions(driver).moveToElement(el).click().perform() |
| Select dropdown |
new Select(driver.findElement(By.id("dropdown"))).selectByValue("1") |
| Handle alert |
driver.switchTo().alert().accept() |
| Switch iframe |
driver.switchTo().frame("frameName") |
| New tab/window |
driver.switchTo().newWindow(WindowType.TAB) |
Reference Files
| File |
When to Read |
reference/cloud-integration.md |
Cloud/Grid setup, parallel, capabilities |
reference/page-object-model.md |
Full POM with base classes, factories |
reference/python-patterns.md |
Python + pytest-selenium |
reference/javascript-patterns.md |
Node.js + Mocha/Jest |
reference/csharp-patterns.md |
C# + NUnit/xUnit |
reference/ruby-patterns.md |
Ruby + RSpec/Capybara |
reference/php-patterns.md |
PHP + Composer + PHPUnit |
reference/debugging-common-issues.md |
Stale elements, timeouts, flaky |
Advanced Playbook
For production-grade patterns, see reference/playbook.md:
| Section |
What's Inside |
| §1 DriverFactory |
Thread-safe, multi-browser, local + remote, headless CI |
| §2 Config Management |
Properties files, env overrides, multi-env support |
| §3 Production BasePage |
20+ helper methods, Shadow DOM, iframe, alerts, Angular/jQuery waits |
| §4 Page Object Example |
Full LoginPage extending BasePage with fluent API |
| §5 Smart Waits |
FluentWait, retry on stale, stable list wait, custom conditions |
| §6 Data-Driven |
CSV, MethodSource, Excel DataProvider (Apache POI) |
| §7 Screenshots |
JUnit 5 Extension + TestNG Listener with Allure attachment |
| §8 Allure Reporting |
Epic/Feature/Story annotations, step-based reporting |
| §9 CI/CD |
GitHub Actions matrix + GitLab CI with Selenium service |
| §10 Parallel |
TestNG XML + JUnit 5 parallel properties |
| §11 Advanced Interactions |
File download, multi-window, network logs |
| §12 Retry Mechanism |
TestNG IRetryAnalyzer for flaky test handling |
| §13 Debugging Table |
11 common exceptions with cause + fix |
| §14 Best Practices |
17-item production checklist |
Limitations
- Use this skill only when the task clearly matches its upstream source and local project context.
- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.
- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
Source: sickn33/agentic-awesome-skills → skills/selenium-skill/SKILL.md
Also appears in: sickn33/agentic-awesome-skills/plugins/agentic-awesome-skills/skills/selenium-skill/SKILL.md, sickn33/agentic-awesome-skills/plugins/agentic-awesome-skills-claude/skills/selenium-skill/SKILL.md
1---2name: selenium-skill3description: Generates production-grade Selenium WebDriver automation scripts and tests in Java, Python, JavaScript, C#, Ruby, or PHP. Supports local execution and TestMu AI cloud with 3000+ browser/OS combinations. Use when the user asks to write Selenium tests, automate with WebDriver, run...4---5
6
7# Selenium Automation Skill
8## When to Use
9
10Use this skill when you need generates production-grade Selenium WebDriver automation scripts and tests in Java, Python, JavaScript, C#, Ruby, or PHP. Supports local execution and TestMu AI cloud with 3000+ browser/OS combinations. Use when the user asks to write Selenium tests, automate with WebDriver, run...
11
12
13You are a senior QA automation architect. You write production-grade Selenium WebDriver
14scripts and tests that run locally or on TestMu AI cloud.
15
16## Step 1 — Execution Target
17
18```
19User says "automate" / "test my site"
20│
21├─ Mentions "cloud", "TestMu", "LambdaTest", "Grid", "cross-browser", "real device"?
22│ └─ TestMu AI cloud (RemoteWebDriver)
23│
24├─ Mentions specific combos (Safari on Windows, old browsers)?
25│ └─ Suggest TestMu AI cloud
26│
27├─ Mentions "locally", "my machine", "ChromeDriver"?
28│ └─ Local execution
29│
30└─ Ambiguous? → Default local, mention cloud for broader coverage
31```
32
33## Step 2 — Language Detection
34
35| Signal | Language | Config |
36|--------|----------|--------|
37| Default / no signal | Java | Maven + JUnit 5 |
38| "Python", "pytest", ".py" | Python | pip + pytest |
39| "JavaScript", "Node", ".js" | JavaScript | npm + Mocha/Jest |
40| "C#", ".NET", "NUnit" | C# | NuGet + NUnit |
41| "Ruby", ".rb", "RSpec" | Ruby | gem + RSpec |
42| "PHP", "Codeception" | PHP | Composer + PHPUnit |
43
44For non-Java languages → read `reference/<language>-patterns.md`
45
46## Step 3 — Scope
47
48| Request Type | Action |
49|-------------|--------|
50| "Write a test for X" | Single test file, inline setup |
51| "Set up Selenium project" | Full project with POM, config, base classes |
52| "Fix/debug test" | Read `reference/debugging-common-issues.md` |
53| "Run on cloud" | Read `reference/cloud-integration.md` |
54
55## Core Patterns — Java (Default)
56
57### Locator Priority
58
59```
601. By.id("element-id") ← Most stable
612. By.name("field-name") ← Form elements
623. By.cssSelector(".class") ← Fast, readable
634. By.xpath("//div[@data-testid]") ← Last resort
64```
65
66**NEVER use:** fragile XPaths like `//div[3]/span[2]/a`, absolute paths.
67
68### Wait Strategy — CRITICAL
69
70```java
71// ✅ ALWAYS use explicit waits
72WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
73WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
74
75// ❌ NEVER use Thread.sleep() or implicit waits mixed with explicit
76Thread.sleep(3000); // FORBIDDEN
77driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); // Don't mix
78```
79
80### Anti-Patterns
81
82| Bad | Good | Why |
83|-----|------|-----|
84| `Thread.sleep(5000)` | Explicit `WebDriverWait` | Flaky, slow |
85| Implicit + explicit waits | Only explicit waits | Unpredictable timeouts |
86| `driver.findElement()` without wait | Wait then find | NoSuchElementException |
87| Absolute XPath | Relative CSS/ID | Breaks on DOM changes |
88| No `driver.quit()` | Always `quit()` in finally/teardown | Leaks browsers |
89
90### Basic Test Structure
91
92```java
93import org.openqa.selenium.WebDriver;
94import org.openqa.selenium.chrome.ChromeDriver;
95import org.openqa.selenium.By;
96import org.openqa.selenium.support.ui.WebDriverWait;
97import org.openqa.selenium.support.ui.ExpectedConditions;
98import org.junit.jupiter.api.*;
99import java.time.Duration;
100
101public class LoginTest {
102 private WebDriver driver;
103 private WebDriverWait wait;
104
105 @BeforeEach
106 void setUp() {
107 driver = new ChromeDriver();
108 wait = new WebDriverWait(driver, Duration.ofSeconds(10));
109 driver.manage().window().maximize();
110 }
111
112 @Test
113 void testLogin() {
114 driver.get("https://example.com/login");
115 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username")))
116 .sendKeys("user@test.com");
117 driver.findElement(By.id("password")).sendKeys("password123");
118 driver.findElement(By.cssSelector("button[type='submit']")).click();
119 wait.until(ExpectedConditions.urlContains("/dashboard"));
120 Assertions.assertTrue(driver.getTitle().contains("Dashboard"));
121 }
122
123 @AfterEach
124 void tearDown() {
125 if (driver != null) driver.quit();
126 }
127}
128```
129
130### Page Object Model — Quick Example
131
132```java
133// pages/LoginPage.java
134public class LoginPage {
135 private WebDriver driver;
136 private WebDriverWait wait;
137
138 private By usernameField = By.id("username");
139 private By passwordField = By.id("password");
140 private By submitButton = By.cssSelector("button[type='submit']");
141
142 public LoginPage(WebDriver driver) {
143 this.driver = driver;
144 this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
145 }
146
147 public void login(String username, String password) {
148 wait.until(ExpectedConditions.visibilityOfElementLocated(usernameField))
149 .sendKeys(username);
150 driver.findElement(passwordField).sendKeys(password);
151 driver.findElement(submitButton).click();
152 }
153}
154```
155
156### TestMu AI Cloud — Quick Setup
157
158```java
159import org.openqa.selenium.remote.RemoteWebDriver;
160import org.openqa.selenium.remote.DesiredCapabilities;
161import java.net.URL;
162import java.util.HashMap;
163
164String username = System.getenv("LT_USERNAME");
165String accessKey = System.getenv("LT_ACCESS_KEY");
166String hub = "https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub";
167
168DesiredCapabilities caps = new DesiredCapabilities();
169caps.setCapability("browserName", "Chrome");
170caps.setCapability("browserVersion", "latest");
171HashMap<String, Object> ltOptions = new HashMap<>();
172ltOptions.put("platform", "Windows 11");
173ltOptions.put("build", "Selenium Build");
174ltOptions.put("name", "My Test");
175ltOptions.put("video", true);
176ltOptions.put("network", true);
177caps.setCapability("LT:Options", ltOptions);
178
179WebDriver driver = new RemoteWebDriver(new URL(hub), caps);
180```
181
182### Test Status Reporting
183
184```java
185// After test — report to TestMu AI dashboard
186((JavascriptExecutor) driver).executeScript(
187 "lambda-status=" + (testPassed ? "passed" : "failed")
188);
189```
190
191## Validation Workflow
192
1931. **Locators**: No absolute XPath, prefer ID/CSS
1942. **Waits**: Only explicit WebDriverWait, zero Thread.sleep()
1953. **Cleanup**: driver.quit() in @AfterEach/teardown
1964. **Cloud**: LT_USERNAME + LT_ACCESS_KEY from env vars
1975. **POM**: Locators in page class, assertions in test class
198
199## Quick Reference
200
201| Task | Command/Code |
202|------|-------------|
203| Run with Maven | `mvn test` |
204| Run single test | `mvn test -Dtest=LoginTest` |
205| Run with Gradle | `./gradlew test` |
206| Parallel (TestNG) | `<suite parallel="tests" thread-count="5">` |
207| Screenshots | `((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE)` |
208| Actions API | `new Actions(driver).moveToElement(el).click().perform()` |
209| Select dropdown | `new Select(driver.findElement(By.id("dropdown"))).selectByValue("1")` |
210| Handle alert | `driver.switchTo().alert().accept()` |
211| Switch iframe | `driver.switchTo().frame("frameName")` |
212| New tab/window | `driver.switchTo().newWindow(WindowType.TAB)` |
213
214## Reference Files
215
216| File | When to Read |
217|------|-------------|
218| `reference/cloud-integration.md` | Cloud/Grid setup, parallel, capabilities |
219| `reference/page-object-model.md` | Full POM with base classes, factories |
220| `reference/python-patterns.md` | Python + pytest-selenium |
221| `reference/javascript-patterns.md` | Node.js + Mocha/Jest |
222| `reference/csharp-patterns.md` | C# + NUnit/xUnit |
223| `reference/ruby-patterns.md` | Ruby + RSpec/Capybara |
224| `reference/php-patterns.md` | PHP + Composer + PHPUnit |
225| `reference/debugging-common-issues.md` | Stale elements, timeouts, flaky |
226
227## Advanced Playbook
228
229For production-grade patterns, see `reference/playbook.md`:
230
231| Section | What's Inside |
232|---------|--------------|
233| §1 DriverFactory | Thread-safe, multi-browser, local + remote, headless CI |
234| §2 Config Management | Properties files, env overrides, multi-env support |
235| §3 Production BasePage | 20+ helper methods, Shadow DOM, iframe, alerts, Angular/jQuery waits |
236| §4 Page Object Example | Full LoginPage extending BasePage with fluent API |
237| §5 Smart Waits | FluentWait, retry on stale, stable list wait, custom conditions |
238| §6 Data-Driven | CSV, MethodSource, Excel DataProvider (Apache POI) |
239| §7 Screenshots | JUnit 5 Extension + TestNG Listener with Allure attachment |
240| §8 Allure Reporting | Epic/Feature/Story annotations, step-based reporting |
241| §9 CI/CD | GitHub Actions matrix + GitLab CI with Selenium service |
242| §10 Parallel | TestNG XML + JUnit 5 parallel properties |
243| §11 Advanced Interactions | File download, multi-window, network logs |
244| §12 Retry Mechanism | TestNG IRetryAnalyzer for flaky test handling |
245| §13 Debugging Table | 11 common exceptions with cause + fix |
246| §14 Best Practices | 17-item production checklist |
247
248## Limitations
249
250- Use this skill only when the task clearly matches its upstream source and local project context.
251- Verify commands, generated code, dependencies, credentials, and external service behavior before applying changes.
252- Do not treat examples as a substitute for environment-specific tests, security review, or user approval for destructive or costly actions.
253
254---
255
256**Source:** [`sickn33/agentic-awesome-skills`](https://github.com/sickn33/agentic-awesome-skills) → `skills/selenium-skill/SKILL.md`
257
258**Also appears in:** `sickn33/agentic-awesome-skills/plugins/agentic-awesome-skills/skills/selenium-skill/SKILL.md`, `sickn33/agentic-awesome-skills/plugins/agentic-awesome-skills-claude/skills/selenium-skill/SKILL.md`