|
| 1 | +# E2E Testing with Playwright |
| 2 | + |
| 3 | +This directory contains end-to-end (E2E) tests for the Iterable Web SDK React example application using [Playwright](https://playwright.dev/). |
| 4 | + |
| 5 | +## Table of Contents |
| 6 | + |
| 7 | +- [Prerequisites](#prerequisites) |
| 8 | +- [Installation](#installation) |
| 9 | +- [Running Tests](#running-tests) |
| 10 | +- [Test Structure](#test-structure) |
| 11 | +- [Page Object Model](#page-object-model) |
| 12 | +- [Configuration](#configuration) |
| 13 | +- [Writing New Tests](#writing-new-tests) |
| 14 | +- [Debugging Tests](#debugging-tests) |
| 15 | +- [CI/CD](#cicd) |
| 16 | + |
| 17 | +## Prerequisites |
| 18 | + |
| 19 | +Before running the E2E tests, ensure you have: |
| 20 | + |
| 21 | +1. **Node.js**: Version 18.12.0 or higher (as specified in `package.json`) |
| 22 | +2. **React Example App Running**: The tests expect the application to be running on `http://localhost:8080` |
| 23 | + |
| 24 | +## Installation |
| 25 | + |
| 26 | +1. **Start the sample app** (from the SDK root directory): |
| 27 | + ```bash |
| 28 | + yarn install:all && yarn start:all:react |
| 29 | + ``` |
| 30 | + This starts both the SDK and React sample app. Navigate to `http://localhost:8080` in your browser. |
| 31 | + |
| 32 | + > **Note**: If port 8080 is taken, the app will run on the next available port (8081, 8082, etc.). Check the compilation logs for the specific port. |
| 33 | +
|
| 34 | +2. **Install Playwright browsers** (from the `react-example` directory): |
| 35 | + ```bash |
| 36 | + yarn playwright:install |
| 37 | + ``` |
| 38 | + |
| 39 | +## Running Tests |
| 40 | + |
| 41 | +### Run E2E Tests |
| 42 | + |
| 43 | +Once the application is running, you can execute the tests: |
| 44 | + |
| 45 | +```bash |
| 46 | +# Run all tests headlessly |
| 47 | +yarn playwright |
| 48 | + |
| 49 | +# Run tests with UI mode (interactive) |
| 50 | +yarn playwright:ui |
| 51 | + |
| 52 | +# Run tests in debug mode |
| 53 | +yarn playwright:debug |
| 54 | + |
| 55 | +# Run specific test file |
| 56 | +yarn playwright authentication.spec.ts |
| 57 | + |
| 58 | +# Run tests in a specific browser |
| 59 | +yarn playwright --project=chromium |
| 60 | +``` |
| 61 | + |
| 62 | +## Test Structure |
| 63 | + |
| 64 | +The E2E tests are organized as follows: |
| 65 | + |
| 66 | +``` |
| 67 | +e2e/ |
| 68 | +├── README.md # This file |
| 69 | +├── authentication.spec.ts # Authentication and navigation tests |
| 70 | +├── uua-testing.spec.ts # UUA (User Update Actions) testing page tests |
| 71 | +└── page-objects/ # Page Object Model implementation |
| 72 | + ├── BasePage.ts # Base page with common functionality |
| 73 | + ├── components/ # Reusable component objects |
| 74 | + │ ├── LoginForm.ts # Login form interactions |
| 75 | + │ └── Navigation.ts # Navigation component interactions |
| 76 | + └── pages/ # Page-specific objects |
| 77 | + ├── EmbeddedMsgsPage.ts # Embedded messages page |
| 78 | + ├── EmbeddedPage.ts # Embedded page |
| 79 | + └── UUATestingPage.ts # UUA testing page |
| 80 | +``` |
| 81 | + |
| 82 | +## Page Object Model |
| 83 | + |
| 84 | +This project uses the Page Object Model (POM) pattern to organize test code: |
| 85 | + |
| 86 | +### BasePage |
| 87 | +- **Location**: `page-objects/BasePage.ts` |
| 88 | +- **Purpose**: Contains common functionality shared across all pages |
| 89 | +- **Features**: Cookie consent handling, page loading utilities, navigation access |
| 90 | + |
| 91 | +### Components |
| 92 | +- **Navigation**: Handles navigation between different sections of the app |
| 93 | +- **LoginForm**: Manages user authentication flows |
| 94 | + |
| 95 | +### Pages |
| 96 | +- **UUATestingPage**: Handles interactions with the UUA testing endpoints |
| 97 | +- **EmbeddedMsgsPage**: Manages embedded messages functionality |
| 98 | +- **EmbeddedPage**: Handles embedded message display and interactions |
| 99 | + |
| 100 | +## Configuration |
| 101 | + |
| 102 | +The Playwright configuration is defined in `playwright.config.ts` (in the `react-example` root): |
| 103 | + |
| 104 | +### Key Settings: |
| 105 | +- **Base URL**: `http://localhost:8080` |
| 106 | +- **Test Directory**: `./e2e` |
| 107 | +- **Browsers**: Chromium, Firefox, WebKit |
| 108 | +- **Retry Strategy**: 2 retries on CI, 0 locally |
| 109 | +- **Test ID Attribute**: `data-test` |
| 110 | +- **Screenshots**: On failure only |
| 111 | +- **Video**: On first retry |
| 112 | +- **Trace**: On first retry |
| 113 | + |
| 114 | +### Timeouts: |
| 115 | +- **Action Timeout**: 10 seconds |
| 116 | +- **Navigation Timeout**: 30 seconds |
| 117 | + |
| 118 | +## Writing New Tests |
| 119 | + |
| 120 | +### 1. Create a Test File |
| 121 | + |
| 122 | +Create a new `.spec.ts` file in the `e2e` directory: |
| 123 | + |
| 124 | +```typescript |
| 125 | +import { test, expect } from '@playwright/test'; |
| 126 | +import { YourPageObject } from './page-objects/pages/YourPageObject'; |
| 127 | + |
| 128 | +test.describe('Your Feature', () => { |
| 129 | + let yourPage: YourPageObject; |
| 130 | + |
| 131 | + test.beforeEach(async ({ page }) => { |
| 132 | + yourPage = new YourPageObject(page); |
| 133 | + await yourPage.goto(); |
| 134 | + await yourPage.acceptCookies(); |
| 135 | + }); |
| 136 | + |
| 137 | + test('should do something', async () => { |
| 138 | + // Your test logic here |
| 139 | + }); |
| 140 | +}); |
| 141 | +``` |
| 142 | + |
| 143 | +### 2. Create Page Objects |
| 144 | + |
| 145 | +If testing a new page, create a corresponding page object: |
| 146 | + |
| 147 | +```typescript |
| 148 | +// page-objects/pages/YourPageObject.ts |
| 149 | +import { Page, Locator, expect } from '@playwright/test'; |
| 150 | +import { BasePage } from '../BasePage'; |
| 151 | + |
| 152 | +export class YourPageObject extends BasePage { |
| 153 | + readonly yourElement: Locator; |
| 154 | + |
| 155 | + constructor(page: Page) { |
| 156 | + super(page); |
| 157 | + this.yourElement = page.getByTestId('your-element'); |
| 158 | + } |
| 159 | + |
| 160 | + async goto() { |
| 161 | + await this.page.goto('/your-route'); |
| 162 | + await this.waitForPageLoad(); |
| 163 | + } |
| 164 | + |
| 165 | + async performAction() { |
| 166 | + await this.yourElement.click(); |
| 167 | + } |
| 168 | +} |
| 169 | +``` |
| 170 | + |
| 171 | +### 3. Best Practices |
| 172 | + |
| 173 | +- **Use `data-test` attributes** for element selection |
| 174 | +- **Extend BasePage** for new page objects |
| 175 | +- **Handle cookie consent** in `beforeEach` hooks |
| 176 | +- **Use meaningful test descriptions** |
| 177 | +- **Group related tests** in `describe` blocks |
| 178 | +- **Wait for elements** to be visible before interacting |
| 179 | + |
| 180 | +## Debugging Tests |
| 181 | + |
| 182 | +### Debug Mode |
| 183 | +```bash |
| 184 | +yarn playwright:debug |
| 185 | +``` |
| 186 | +This opens the Playwright Inspector, allowing you to step through tests. |
| 187 | + |
| 188 | +### UI Mode |
| 189 | +```bash |
| 190 | +yarn playwright:ui |
| 191 | +``` |
| 192 | +Provides an interactive UI to run and debug tests. |
| 193 | + |
| 194 | +### View Test Reports |
| 195 | +After running tests, view the HTML report: |
| 196 | +```bash |
| 197 | +npx playwright show-report |
| 198 | +``` |
| 199 | + |
| 200 | +### Screenshots and Videos |
| 201 | +Failed tests automatically capture: |
| 202 | +- Screenshots (in `test-results/`) |
| 203 | +- Videos (on retry) |
| 204 | +- Traces (on retry) |
| 205 | + |
| 206 | +## CI/CD |
| 207 | + |
| 208 | +The configuration is optimized for CI environments: |
| 209 | + |
| 210 | +- **Parallel Execution**: Disabled on CI for stability |
| 211 | +- **Retries**: 2 retries on CI |
| 212 | +- **Fail Fast**: Tests fail if `test.only` is left in code |
| 213 | +- **Reporters**: HTML reports for detailed results |
| 214 | + |
| 215 | +### Environment Variables |
| 216 | +- `CI`: Enables CI-specific settings when set to any truthy value |
| 217 | + |
| 218 | +## Troubleshooting |
| 219 | + |
| 220 | +### Common Issues |
| 221 | + |
| 222 | +1. **Application not running**: Ensure the sample app is running and accessible at `http://localhost:8080` |
| 223 | + |
| 224 | +2. **Timeouts**: If tests are timing out, check if the application is responsive and consider increasing timeout values |
| 225 | + |
| 226 | +3. **Element not found**: Verify that `data-test` attributes exist on the target elements |
| 227 | + |
| 228 | +4. **Browser installation**: Run `yarn playwright:install` if browsers are missing |
| 229 | + |
| 230 | +### Getting Help |
| 231 | + |
| 232 | +- Check the [Playwright documentation](https://playwright.dev/docs/intro) |
| 233 | +- Review existing test files for patterns and examples |
| 234 | +- Use `playwright:debug` mode to step through failing tests |
| 235 | + |
| 236 | +## Available Test Scripts |
| 237 | + |
| 238 | +From the `react-example` directory: |
| 239 | + |
| 240 | +```bash |
| 241 | +yarn playwright # Run all tests headlessly |
| 242 | +yarn playwright:ui # Run with interactive UI |
| 243 | +yarn playwright:debug # Run in debug mode |
| 244 | +yarn playwright:install # Install Playwright browsers |
| 245 | +``` |
| 246 | + |
| 247 | +## Test Coverage |
| 248 | + |
| 249 | +Current test files cover: |
| 250 | + |
| 251 | +- **Authentication flows** (`authentication.spec.ts`) |
| 252 | +- **UUA testing endpoints** (`uua-testing.spec.ts`) |
0 commit comments