UNPKG

jest-e2e

Version:

A powerful Jest + Puppeteer E2E testing framework with built-in device automation, data builders, and CLI

456 lines (371 loc) • 11.8 kB
# Jest E2E Testing Framework A powerful Jest + Puppeteer E2E testing framework with built-in device automation, data builders, and CLI. ## šŸš€ Features - **Easy Setup**: Get started with E2E testing in minutes - **Device Automation**: Built-in browser automation with simple API - **Data Builders**: Flexible test data generation with inheritance - **CLI Tool**: Comprehensive command-line interface - **Step Logging**: Real-time test step tracking - **Single Test Enforcement**: One test per file for better organization - **ES6 Module Support**: Modern JavaScript syntax - **Headless & Visible Modes**: Perfect for CI/CD and local development ## šŸ“¦ Installation ### Global Installation (Recommended) ```bash npm install -g jest-e2e@latest ``` ### Project Installation ```bash npm install jest-e2e@latest npx jest-e2e --help ``` ## šŸƒā€ā™‚ļø Quick Start ### 1. Install and Initialize ```bash mkdir my-e2e-tests cd my-e2e-tests npm init -y npm install jest-e2e@latest # Just run it - auto-initializes with examples on first run npx jest-e2e ``` ### 2. That's it! šŸŽ‰ The framework automatically: - āœ… Detects it's your first run - āœ… Updates your `package.json` with ES module support and Jest configuration - āœ… Adds helpful npm scripts (`npm run jest-e2e`, `npm run jest-e2e:visible`, etc.) - āœ… Creates `__tests__/`, `databuilders/`, and `config/` directories - āœ… Copies example tests and configuration files - āœ… Sets up global access to Jest E2E functions - āœ… Installs required dependencies automatically - āœ… Runs the example tests to show you it works ### 3. Use the New npm Scripts After initialization, you can use these convenient scripts: ```bash # Run all E2E tests (headless) npm run jest-e2e # Run with visible browser for debugging npm run jest-e2e:visible # Run in watch mode npm run jest-e2e:watch # Or use the CLI directly with more options npx jest-e2e --repl ``` ### 4. Customize for Your App Edit the example tests in `__tests__/`: ```javascript // __tests__/my-login-test-e2e.js test('User can login successfully', async () => { const { device } = await E2ESetup(); const { userEmail, userPassword } = getTestData(); await device.navigate('https://your-app.com/login'); // šŸ‘ˆ Change URL await device.fill('#email', userEmail); // šŸ‘ˆ Update selectors await device.fill('#password', userPassword); await device.click('#login-button'); await device.waitForSelector('.dashboard'); expect(await device.getInnerText('.welcome')).toContain('Welcome'); }); ``` ## šŸŽÆ CLI Usage ```bash jest-e2e [test_name] [options] ``` ### Options - `--useLocalBrowser true` - Run with visible browser - `--repl` - Keep browser open after test completion - `--debug` - Enable debug mode - `--watch` - Watch mode for development - `--verbose` - Detailed output - `--timeout <ms>` - Custom timeout (default: 30000) - `--slowmo <ms>` - Add delay between actions - `--screenshot` - Take screenshots on failure - `--silent` - No step logging - `--help` - Show help ### Examples ```bash # Run all tests in headless mode jest-e2e # Run specific test with visible browser jest-e2e login-success --useLocalBrowser true # Debug mode with step logging jest-e2e payment-flow --debug --verbose # Keep browser open for inspection jest-e2e checkout-process --repl # Slow motion for demonstrations jest-e2e user-journey --slowmo 500 --useLocalBrowser true ``` ## šŸ”§ API Reference ### E2ESetup() Main setup function that configures test environment with data builders and devices: ```javascript const { getTestData, getDevices } = E2ESetup({ databuilder: AgentTestDataBuilder(), devices: { device: createChromeE2EApi({}), }, }); // Use in your tests const { device } = getDevices(); const { userEmail, userPassword } = getTestData(); ``` ### Device API Built-in browser automation methods: ```javascript // Navigation await device.navigate(url); await device.goBack(); await device.refresh(); // Interactions await device.click(selector); await device.fill(selector, value); await device.select(selector, value); await device.hover(selector); // Waiting await device.waitForSelector(selector); await device.waitForTimeout(ms); // Information const text = await device.getInnerText(selector); const value = await device.getValue(selector); const isVisible = await device.isVisible(selector); ``` ### Data Builders Generate test data with inheritance: ```javascript // Import in your test files import { AgentTestDataBuilder } from '../databuilders/agent-test-data-builder.js'; // Get test data (available globally in tests) const { userEmail, userPassword } = getTestData(); // Custom data builder export function myCustomDataBuilder() { return { ...baseDataBuilder(), customField: 'custom value', genImp() { return 'custom-implementation'; }, getVersion() { return '1.0.0'; } }; } ``` ### Step Logging Track test progress (available globally): ```javascript logStep('Navigating to login page'); logStep('Filling user credentials'); logStep('Submitting login form'); ``` ## šŸ“ Project Structure After running `npx jest-e2e` for the first time, your project will have: ``` your-project/ ā”œā”€ā”€ __tests__/ # Your E2E tests (auto-created with examples) │ ā”œā”€ā”€ example-login-success-e2e.js │ ā”œā”€ā”€ example-login-invalid-e2e.js │ └── example-form-validation-e2e.js ā”œā”€ā”€ databuilders/ # Test data builders (auto-created) │ ā”œā”€ā”€ base-data-builder.js │ └── agent-test-data-builder.js ā”œā”€ā”€ config/ # Configuration files (auto-created) │ └── test-setup.js # Global Jest E2E setup ā”œā”€ā”€ jest-puppeteer.config.js # Puppeteer configuration (auto-created) └── package.json # Updated with ES modules & Jest config ``` **Auto-Generated Files:** The framework automatically creates all necessary files: - **Example Tests**: Three example tests showing different patterns - **Data Builders**: Base and example data builders for test data generation - **Configuration**: Jest setup and Puppeteer configuration - **Package Configuration**: Your package.json gets updated with proper ES module and Jest settings ## šŸ—ļø Custom Configuration ### Automatic Package.json Updates When you run `npx jest-e2e` for the first time, the framework automatically updates your `package.json` with: ```json { "type": "module", // Enables ES6 imports "scripts": { "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest", "jest-e2e": "jest-e2e", // Convenient E2E scripts "jest-e2e:visible": "jest-e2e --useLocalBrowser true", "jest-e2e:watch": "jest-e2e --watch" }, "jest": { // Jest configuration for E2E "preset": "jest-puppeteer", "testMatch": ["**/*-e2e.js"], "testTimeout": 30000, "setupFilesAfterEnv": ["./config/test-setup.js"] }, "devDependencies": { // Required testing dependencies "jest": "^29.7.0", "puppeteer": "^24.9.0", "jest-puppeteer": "^11.0.0" } } ``` This automatic configuration eliminates the need for manual setup and ensures everything works out of the box! ### Custom Puppeteer Configuration Create `jest-puppeteer.config.js`: ```javascript export default { launch: { headless: process.env.CI === 'true', defaultViewport: { width: 1280, height: 720 }, args: ['--no-sandbox', '--disable-setuid-sandbox'] }, server: { command: 'npm start', port: 3000, launchTimeout: 10000 } }; ``` ## šŸŽÆ Writing Tests ### Basic Test Structure Since Jest E2E functions are globally available, you can write tests without imports: ```javascript /* eslint-disable no-undef */ "use strict"; // Import your specific data builders import { AgentTestDataBuilder } from '../databuilders/agent-test-data-builder.js'; const { getTestData, getDevices } = E2ESetup({ databuilder: AgentTestDataBuilder(), devices: { device: createChromeE2EApi({}), }, }); test("User can complete checkout", async () => { const { device } = getDevices(); const { userEmail, userPassword } = getTestData(); logStep('Navigate to login page'); await device.navigate("https://your-app.com/login"); logStep('Fill login credentials'); await device.type("#email", userEmail); await device.type("#password", userPassword); logStep('Submit login form'); await device.click("#login-button"); // Verify success await device.expect("body").toContain("Dashboard"); }); ``` ### Single Test Rule Each test file must contain exactly one test function: ```javascript // āœ… Good - one test per file test('User can complete checkout', async () => { // test implementation }); // āŒ Bad - multiple tests in one file test('Test 1', async () => {}); test('Test 2', async () => {}); // This will throw an error ``` ### Test File Naming Use `-e2e.js` suffix for test files: - `login-success-e2e.js` - `user-registration-e2e.js` - `payment-flow-e2e.js` ### Data Builder Pattern ```javascript // databuilders/user-data-builder.js export function userDataBuilder() { return { ...baseDataBuilder(), // Available globally userEmail: 'test@example.com', userPassword: 'password123', userFullName: 'Test User', genImp() { return 'user-builder-v1'; }, getVersion() { return '1.0.0'; } }; } ``` ## šŸŽÆ Best Practices ### 1. Use Descriptive Test Names ```javascript test('User can login with valid credentials and access dashboard', async () => { // test implementation }); ``` ### 2. Implement Page Object Pattern ```javascript class LoginPage { constructor(device) { this.device = device; } async login(email, password) { await this.device.type('#email', email); await this.device.type('#password', password); await this.device.click('#login-button'); } } ``` ### 3. Use Step Logging ```javascript test('Complete user journey', async () => { const { device } = await E2ESetup(); logStep('Navigate to homepage'); await device.navigate('https://example.com'); logStep('Click sign up button'); await device.click('#signup'); logStep('Fill registration form'); // form filling... }); ``` ## šŸ› Debugging ### Visual Debugging ```bash # Run with visible browser jest-e2e my-test --useLocalBrowser true # Keep browser open for inspection jest-e2e my-test --repl # Slow motion for better visibility jest-e2e my-test --slowmo 1000 --useLocalBrowser true ``` ### Debug Mode ```bash # Enable debug output jest-e2e my-test --debug --verbose ``` ### Screenshots ```bash # Take screenshots on failure jest-e2e my-test --screenshot ``` ## šŸ“Š CI/CD Integration ### GitHub Actions ```yaml name: E2E Tests on: [push, pull_request] jobs: e2e: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '18' - run: npm install - run: npx jest-e2e --silent ``` ### GitLab CI ```yaml e2e_tests: image: node:18 script: - npm install - npx jest-e2e --silent ``` ## šŸ¤ Contributing 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## šŸ“„ License MIT License - see LICENSE file for details. ## šŸ†˜ Support - [GitHub Issues](https://github.com/IbrahimAni/jest_e2e/issues) - [Documentation](https://github.com/yourusername/jest-e2e#readme) - [CLI Reference](./CLI_README.md) - [Example Tests Guide](./EXAMPLES.md) --- Made with ā¤ļø for the testing community