You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ghost/e2e/README.md

209 lines
7.0 KiB

# Ghost End-To-End Test Suite
This test suite runs automated browser tests against a running Ghost instance to ensure critical user journeys work correctly.
## Quick Start
### Prerequisites
- Docker and Docker Compose installed
- Node.js and Yarn installed
### Running Tests
From the repository root:
```bash
# Install dependencies
yarn
# Build Docker images
yarn docker:build
# Run the e2e tests
yarn test:e2e
```
### Running Specific Tests
Within `e2e` folder, run one of the following commands:
```bash
# All tests
yarn test
# Specific test file
yarn test specific/folder/testfile.spec.ts
# Matching a pattern
yarn test --grep "homepage"
# With browser visible (for debugging)
yarn test --debug
```
## Tests Development
The test suite is organized into separate directories for different areas/functions:
### **Current Test Suites**
- `tests/public/` - Public-facing site tests (homepage, posts, etc.)
- `tests/admin/` - Ghost admin panel tests (login, content creation, settings)
We can decide on additional sub-folders as we go.
Example structure for admin tests:
```text
tests/admin/
├── login.spec.ts
├── posts.spec.ts
└── settings.spec.ts
```
Project folder structure can be seen below:
```text
e2e/
├── tests/ # All the tests
│ ├── public/ # Public site tests
│ │ └── testname.spec.ts # Test cases
│ ├── admin/ # Admin site tests
│ │ └── testname.spec.ts # Test cases
│ ├── global.setup.ts # Global setup script
│ ├── global.teardown.ts # Global teardown script
│ └── .eslintrc.js # Test-specific ESLint config
├── helpers/ # All helpers that support the tests, utilities, fixtures, page objects etc.
│ ├── playwright/ # Playwright specific helpers
│ │ └── fixture.ts # Playwright fixtures
│ ├── pages/ # Page Object Models
│ │ └── HomePage.ts # Page Object
│ ├── utils/ # Utils
│ │ └── math.ts # Math related utils
│ └── index.ts # Main exports
├── playwright.config.mjs # Playwright configuration
├── package.json # Dependencies and scripts
└── tsconfig.json # TypeScript configuration
```
### Writing Tests
Tests use [Playwright Test](https://playwright.dev/docs/writing-tests) framework with page objects.
Aim to format tests in Arrange Act Assert style - it will help you with directions when writing your tests.
```typescript
test.describe('Ghost Homepage', () => {
test('loads correctly', async ({page}) => {
// ARRANGE - setup fixtures, create helpers, prepare things that helps will need to be executed
const homePage = new HomePage(page);
// ACT - do the actions you need to do, to verify certain behaviour
await homePage.goto();
// ASSERT
await expect(homePage.title).toBeVisible();
});
});
```
### Using Page Objects
Page objects encapsulate page elements, and interactions. To read more about them, check [this link out](https://www.selenium.dev/documentation/test_practices/encouraged/page_object_models/) and [this link](https://martinfowler.com/bliki/PageObject.html).
```typescript
// Create a page object for admin login
export class AdminLoginPage {
private pageUrl:string;
constructor(private page: Page) {
this.pageUrl = '/ghost'
}
async goto(urlToVisit = this.pageUrl) {
await this.page.goto(urlToVisit);
}
async login(email: string, password: string) {
await this.page.fill('[name="identification"]', email);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
}
```
### Global Setup and Teardown
Tests use [Project Dependencies](https://playwright.dev/docs/test-global-setup-teardown#option-1-project-dependencies) to define special tests as global setup and teardown tests:
- Global Setup: `tests/global.setup.ts` - runs once before all tests
- Global Teardown: `tests/global.teardown.ts` - runs once after all tests
### Playwright Fixtures
[Playwright Fixtures](https://playwright.dev/docs/test-fixtures) are defined in `helpers/playwright/fixture.ts` and provide reusable test setup/teardown logic.
For example, a `ghostInstance` fixture creates a new Ghost instance with its own database for each test, to ensure isolation between tests.
### Test Isolation
Test isolation is extremely important to avoid flaky tests that are hard to debug. For the most part, you shouldn't have to worry about this when writing tests, because each test gets a fresh Ghost instance with its own database:
- Global setup (`tests/global.setup.ts`):
- Starts shared services (MySQL, Tinybird, etc.)
- Runs Ghost migrations to create a template database
- Saves a snapshot of the template database using `mysqldump`
- Before each test (`helpers/playwright/fixture.ts`):
- Creates a new database by restoring from the template snapshot
- Starts a new Ghost container connected to the new database
- After each test (`helpers/playwright/fixture.ts`):
- Stops and removes the Ghost container
- Drops the test database
- Global teardown (`tests/global.teardown.ts`):
- Stops and removes shared services
### Best Practices
1. **Use page object patterns** to separate page elements, actions on the pages, complex logic from tests. They should help you make them more readable and UI elements reusable.
2. **Add meaningful assertions** beyond just page loads. Keep assertions in tests.
3. **Use `data-testid` attributes** for reliable element selection, in case you **cannot** locate elements in a simple way. Example: `page.getByLabel('User Name')`. Avoid, css, xpath locators - they make tests brittle.
4. **Clean up test data** when tests modify Ghost state
5. **Group related tests** in describe blocks
## CI Integration
Tests run automatically in GitHub Actions on every PR and commit to `main`.
### CI Process
1. **Setup**: Ubuntu runner with Node.js and MySQL
2. **Docker Build & Push**: Build Ghost image and push to GitHub Container Registry
3. **Pull Images**: Pull Ghost, MySQL, Tinybird, etc. images
4. **Test Execution**:
- Wait for Ghost to be ready
- Run Playwright tests
- Upload test artifacts
## Available Scripts
From the e2e directory:
```bash
# Run all tests
yarn test
# Run TypeScript type checking
yarn test:types
# Lint code and tests
yarn lint
# Build (for utilities)
yarn build
yarn dev # Watch mode for TypeScript compilation
```
## Resolving issues
### Test Failures
1. **Screenshots**: Playwright captures screenshots on failure
2. **Traces**: Available in `test-results/` directory
3. **Debug Mode**: Run with `yarn test --debug` or `yarn test --ui` to see browser
4. **Verbose Logging**: Check CI logs for detailed error information