e2e-test-developer
Provides patterns and structure for E2E testing in Eclipse Che/Dev Spaces environments.
Install
mkdir -p .claude/skills/e2e-test-developer && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5240" && unzip -o skill.zip -d .claude/skills/e2e-test-developer && rm skill.zipInstalls to .claude/skills/e2e-test-developer
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Comprehensive E2E test development guidance for Eclipse Che / Red Hat OpenShift Dev Spaces. Use this skill when writing, modifying, or reviewing TypeScript Mocha Selenium tests, page objects, utilities, or test infrastructure. Provides code style rules, patterns, dependency injection setup, and best practices.Key capabilities
- →Develop TypeScript Mocha Selenium test suites
- →Implement Page Object models using dependency injection
- →Configure test infrastructure and environment variables
- →Execute API-only tests without browser dependencies
- →Generate Allure test reports for analysis
How it works
The skill provides a standardized structure for E2E tests using Inversify for dependency injection and Mocha for test execution. It enforces strict file headers, class member ordering, and explicit TypeScript type annotations.
Inputs & outputs
When to use e2e-test-developer
- →Writing Selenium test specs
- →Building page object models
- →Testing IDE features
About this skill
Eclipse Che E2E TypeScript Mocha Selenium Test Development Skill
You are a Software Quality Engineer, who is an expert developer for Eclipse Che / Red Hat OpenShift Dev Spaces E2E tests. This skill provides comprehensive guidance for developing and maintaining E2E TypeScript Mocha Selenium tests.
Project Overview
This is the E2E test suite for Eclipse Che / Red Hat OpenShift Dev Spaces. It uses:
- Selenium WebDriver with Chrome browser
- Mocha (TDD style -
suite(),test(),suiteSetup(),suiteTeardown()) - TypeScript with strict type checking
- Inversify for dependency injection
- Chai for assertions
- Allure for test reporting
Directory Structure
| Directory | Purpose |
|---|---|
specs/ | Test specifications organized by category (api/, factory/, dashboard-samples/, miscellaneous/) |
pageobjects/ | Page Object classes for UI elements (dashboard/, ide/, login/, openshift/, git-providers/, webterminal/) |
utils/ | Utilities (DriverHelper, BrowserTabsUtil, Logger, API handlers, KubernetesCommandLineToolsExecutor) |
tests-library/ | Reusable test helpers (WorkspaceHandlingTests, LoginTests, ProjectAndFileTests) |
constants/ | Environment variable mappings (BASE_TEST_CONSTANTS, TIMEOUT_CONSTANTS, FACTORY_TEST_CONSTANTS, etc.) |
configs/ | Mocha config, Inversify container (inversify.config.ts), shell scripts |
suites/ | Test suite configurations for different environments |
driver/ | Chrome driver configuration |
build/dockerfiles/ | Docker image for running tests |
Essential Commands
# Install dependencies
npm ci
# Lint and format
npm run lint
npm run prettier
# Build TypeScript only
npm run tsc
# Run all tests (requires environment variables)
export TS_SELENIUM_BASE_URL=<che-url>
export TS_SELENIUM_OCP_USERNAME=<username>
export TS_SELENIUM_OCP_PASSWORD=<password>
npm run test
# Run a single test file (without .spec.ts extension)
export USERSTORY=SmokeTest
npm run test
# Run API-only tests (no browser)
export USERSTORY=EmptyWorkspaceAPI
npm run driver-less-test
# View Allure test report
npm run open-allure-dasboard
CODE STYLE REQUIREMENTS (CRITICAL)
File Header (Required for ALL .ts files)
Every TypeScript file MUST start with this exact header:
/** *******************************************************************
* copyright (c) 2026 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
Page Object and Utility Classes
- Class Declaration with Dependency Injection
- Use
@injectable()decorator on ALL page objects and utilities - Use constructor injection with
@inject()decorators
- Use
import { inject, injectable } from 'inversify';
import 'reflect-metadata';
import { CLASSES } from '../../configs/inversify.types';
@injectable()
export class MyPageObject {
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
}
- Public Methods
- Declare public methods WITHOUT the
publickeyword - Add
Logger.debug()at the START of every public method - Always specify explicit return types
- Declare public methods WITHOUT the
async clickButton(timeout: number = TIMEOUT_CONSTANTS.TS_CLICK_DASHBOARD_ITEM_TIMEOUT): Promise<void> {
Logger.debug();
await this.driverHelper.waitAndClick(MyPage.BUTTON_LOCATOR, timeout);
}
- Locators
- Static locators:
private static readonlyfields of typeBy - Dynamic locators:
privatemethods that returnBy - NEVER declare locators as constants inside methods
- Static locators:
// Static locators (correct)
private static readonly SUBMIT_BUTTON: By = By.xpath('//button[@type="submit"]');
private static readonly INPUT_FIELD: By = By.id('input-field');
// Dynamic locators (correct)
private getItemLocator(itemName: string): By {
return By.xpath(`//div[text()="${itemName}"]`);
}
// WRONG - Never do this inside a method
async wrongMethod(): Promise<void> {
const locator: By = By.xpath('//button'); // AVOID THIS
}
Member Ordering (Enforced by ESLint)
Classes must follow this order:
- Static fields
- Public fields
- Instance fields
- Protected fields
- Private fields
- Abstract fields
- Constructor
- Public static methods
- Protected static methods
- Private static methods
- Public methods
- Protected methods
- Private methods
Test File Conventions
-
Naming
- UI tests:
*.spec.ts(e.g.,Factory.spec.ts) - API-only tests:
*API.spec.ts(e.g.,EmptyWorkspaceAPI.spec.ts)
- UI tests:
-
Mocha TDD Style (Required)
- Use
suite(),test(),suiteSetup(),suiteTeardown() - NEVER use arrow functions in test declarations (Mocha context issue)
- Use
suite('My Test Suite', function (): void {
// Inject dependencies inside suite() to avoid unnecessary execution
const dashboard: Dashboard = e2eContainer.get(CLASSES.Dashboard);
const loginTests: LoginTests = e2eContainer.get(CLASSES.LoginTests);
suiteSetup('Login to application', async function (): Promise<void> {
await loginTests.loginIntoChe();
});
test('Verify dashboard is visible', async function (): Promise<void> {
await dashboard.waitPage();
});
suiteTeardown('Cleanup', async function (): Promise<void> {
// cleanup code
});
});
- Dependency Injection in Tests
- Import container:
import { e2eContainer } from '../../configs/inversify.config'; - Import types:
import { CLASSES, TYPES } from '../../configs/inversify.types'; - Get instances inside suite() function
- Import container:
import { e2eContainer } from '../../configs/inversify.config';
import { CLASSES, TYPES } from '../../configs/inversify.types';
suite('Test Suite', function (): void {
const workspaceHandlingTests: WorkspaceHandlingTests = e2eContainer.get(CLASSES.WorkspaceHandlingTests);
const testWorkspaceUtil: ITestWorkspaceUtil = e2eContainer.get(TYPES.WorkspaceUtil);
// ... test implementation
});
TypeScript Requirements
- Explicit Type Annotations Required
- All parameters must have type annotations
- All property declarations must have type annotations
- All variable declarations must have type annotations
- All functions must have explicit return types
// Correct
async function doSomething(param: string, timeout: number): Promise<void> {
const result: string = await someOperation();
}
// Wrong - missing types
async function doSomething(param, timeout) {
const result = await someOperation();
}
-
Naming Conventions
- Variables: camelCase or UPPER_CASE
- No leading/trailing underscores
-
String Quotes
- Use single quotes for strings
-
Comments
- Comments must start with lowercase (capitalized-comments: never)
- Mark workarounds with
// todoand issue number:// todo commented due to issue crw-1010
Prettier and ESLint
- Pre-commit hooks run automatically via Husky
- Run
npm run prettierto fix formatting - Run
npm run lintto fix linting issues
Environment Variables
Core variables (defined in constants/ directory):
| Variable | Description |
|---|---|
TS_SELENIUM_BASE_URL | Che/DevSpaces dashboard URL |
TS_SELENIUM_OCP_USERNAME | OpenShift username |
TS_SELENIUM_OCP_PASSWORD | OpenShift password |
USERSTORY | Specific test file to run (without .spec.ts) |
TS_PLATFORM | openshift (default) or kubernetes |
TS_SELENIUM_FACTORY_GIT_REPO_URL | Git repo for factory tests |
TS_SELENIUM_VALUE_OPENSHIFT_OAUTH | Enable OAuth (true/false) |
TS_SELENIUM_LOG_LEVEL | Logging level (TRACE, DEBUG, INFO, etc.) |
DELETE_WORKSPACE_ON_SUCCESSFUL_TEST | Delete workspace on success |
Adding New Page Objects
- Create file in appropriate
pageobjects/subdirectory - Add
@injectable()decorator - Register in
configs/inversify.config.ts - Add class identifier in
configs/inversify.types.ts
// 1. Create pageobjects/dashboard/NewPage.ts
@injectable()
export class NewPage {
private static readonly ELEMENT_LOCATOR: By = By.id('element');
constructor(@inject(CLASSES.DriverHelper) private readonly driverHelper: DriverHelper) {}
async waitForElement(): Promise<void> {
Logger.debug();
await this.driverHelper.waitVisibility(NewPage.ELEMENT_LOCATOR);
}
}
// 2. Add to configs/inversify.types.ts
const CLASSES: any = {
// ... existing classes
NewPage: 'NewPage'
};
// 3. Add to configs/inversify.config.ts
import { NewPage } from '../pageobjects/dashboard/NewPage';
e2eContainer.bind<NewPage>(CLASSES.NewPage).to(NewPage);
Adding New Tests
- Create file in appropriate
specs/subdirectory - Follow naming convention (*.spec.ts for UI, *API.spec.ts for API)
- Use TDD style (suite, te
Content truncated.
When not to use it
- →Non-TypeScript test environments
- →Projects outside Eclipse Che or Red Hat OpenShift Dev Spaces
Prerequisites
Limitations
- →Requires specific file headers for all TypeScript files
- →Strict class member ordering enforced by ESLint
- →Tests must use Mocha TDD style without arrow functions
How it compares
Unlike generic Selenium setups, this skill enforces a specific architectural pattern with mandatory dependency injection and strict file-level metadata requirements.
Compared to similar skills
e2e-test-developer side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| e2e-test-developer (this skill) | 4 | 6mo | Review | Advanced |
| testing-workflow | 16 | 9mo | Review | Intermediate |
| playwright-pro | 8 | 3mo | Review | Intermediate |
| s2-lint | 2 | 6mo | Review | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
testing-workflow
amo-tech-ai
Comprehensive testing workflow for E2E, integration, and unit tests. Use when testing applications layer-by-layer, validating user journeys, or running test suites.
playwright-pro
alirezarezvani
Production-grade Playwright testing toolkit. Use when the user mentions Playwright tests, end-to-end testing, browser automation, fixing flaky tests, test migration, CI/CD testing, or test suites. Generate tests, fix flaky failures, migrate from Cypress/Selenium, sync with TestRail, run on BrowserStack. 55 templates, 3 agents, smart reporting.
s2-lint
antvis
After modifying S2 project code, you must run lint to ensure there are no errors, avoiding issues when pushing to git.
testrail
alirezarezvani
Sync tests with TestRail. Use when user mentions "testrail", "test management", "test cases", "test run", "sync test cases", "push results to testrail", or "import from testrail".
azure-microsoft-playwright-testing-ts
microsoft
Run Playwright tests at scale using Azure Playwright Workspaces (formerly Microsoft Playwright Testing). Use when scaling browser tests across cloud-hosted browsers, integrating with CI/CD pipelines, or publishing test results to the Azure portal.
browserstack
alirezarezvani
Run tests on BrowserStack. Use when user mentions "browserstack", "cross-browser", "cloud testing", "browser matrix", "test on safari", "test on firefox", or "browser compatibility".