CI Go Report Card License: MIT Go Version
A production-quality end-to-end test framework built with Go and Playwright. Designed as a starting point for QA engineers who want to write browser automation tests in Go.
graph TD
A[Test Files] --> B[Page Objects]
A --> C[Test Helpers]
B --> D[BasePage]
C --> E[BrowserManager]
C --> F[Screenshot Helper]
C --> G[Report Generator]
E --> H[Playwright-Go]
H --> I[Chromium]
H --> J[Firefox]
H --> K[WebKit]
subgraph Config
L[config.yaml] --> M[Config Loader]
N[Env Variables] --> M
end
M --> E
M --> F
M --> G
graph LR
subgraph "Page Object Model"
BP[BasePage<br/>Navigate, WaitFor] --> TP[TodoPage]
BP --> LP[LoginPage]
BP --> DLP[DynamicLoadingPage]
BP --> DP[DropdownPage]
end
playwright-go-framework/
├── .github/workflows/ci.yml # GitHub Actions CI (multi-browser matrix)
├── config/
│ └── config.go # Configuration management (YAML + env vars)
├── helpers/
│ ├── browser.go # Browser lifecycle (launch, context, page)
│ ├── screenshot.go # Screenshot capture utilities
│ └── report.go # HTML/JSON test report generation
├── pages/
│ ├── base_page.go # Shared page methods (navigation, waits)
│ ├── todo_page.go # TodoMVC page object
│ ├── login_page.go # Login form page object
│ ├── dynamic_loading_page.go # Dynamic loading page object
│ └── dropdown_page.go # Dropdown page object
├── tests/
│ ├── setup_test.go # TestMain — global browser lifecycle
│ ├── todo_test.go # TodoMVC tests (add, complete, filter, delete)
│ ├── login_test.go # Login tests (valid, invalid, logout flow)
│ ├── dynamic_loading_test.go # Wait/async loading tests
│ ├── dropdown_test.go # Form interaction tests
│ ├── screenshot_test.go # Screenshot capture tests
│ └── network_test.go # Network interception & mocking tests
├── config.yaml # Default configuration
├── Dockerfile # Container for CI/headless runs
├── docker-compose.yml # Docker Compose for easy test execution
├── Makefile # Common tasks
└── README.md
- Go 1.22+
- Git
# Clone the repository git clone https://github.com/qambar/playwright-go-framework.git cd playwright-go-framework # Install dependencies and Playwright browsers make install
# Run all tests (Chromium, headless) make test # Run with a specific browser make test-firefox make test-webkit # Run in headed mode (see the browser) make test-headed # Run with gotestsum for better output make test-verbose # Generate test reports make test-report
# Run tests in Docker (no local browser install needed) make docker-test # Or with a specific browser BROWSER=firefox docker compose run --rm tests
Configuration is loaded in order of precedence:
- Environment variables (highest priority)
- config.yaml file
- Default values (built into code)
| Variable | Default | Description |
|---|---|---|
BASE_URL |
https://the-internet.herokuapp.com |
Base URL for tests |
BROWSER |
chromium |
Browser: chromium, firefox, webkit |
HEADLESS |
true |
Run browser headless |
SLOW_MO |
0 |
Slow down operations (ms) |
TIMEOUT |
30000 |
Default timeout (ms) |
SCREENSHOT_ON_FAILURE |
true |
Auto-capture on test failure |
SCREENSHOT_DIR |
reports/screenshots |
Screenshot output directory |
package pages import "github.com/playwright-community/playwright-go" type MyPage struct { *BasePage heading playwright.Locator button playwright.Locator } func NewMyPage(page playwright.Page) *MyPage { return &MyPage{ BasePage: NewBasePage(page), heading: page.Locator("h1"), button: page.Locator("#submit"), } } func (mp *MyPage) Goto() error { return mp.Navigate("/my-page") } func (mp *MyPage) GetHeading() (string, error) { return mp.heading.TextContent() }
package tests import ( "testing" "github.com/qambar/playwright-go-framework/helpers" "github.com/qambar/playwright-go-framework/pages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestMyPage_Heading(t *testing.T) { t.Parallel() page := helpers.SetupTest(t) mp := pages.NewMyPage(page) require.NoError(t, mp.Goto()) heading, err := mp.GetHeading() require.NoError(t, err) assert.Equal(t, "Expected Heading", heading) }
helpers.SetupTest(t)— Creates an isolated browser context + page, registers cleanup, captures screenshot on failuret.Parallel()— Tests run in parallel by default; each gets its own browser contextrequire.NoError— Stops the test immediately on error (use for setup steps)assert.Equal— Records failure but continues (use for assertions)
| Test | Playwright Features Demonstrated |
|---|---|
todo_test.go |
Navigation, form input, DOM assertions, element interaction |
login_test.go |
Form submission, text content verification, visibility checks |
dynamic_loading_test.go |
Auto-waiting, explicit waits, async content |
dropdown_test.go |
Select/dropdown interaction, option selection |
screenshot_test.go |
Full-page screenshots, element screenshots |
network_test.go |
Route interception, response mocking, request waiting |
The GitHub Actions pipeline runs tests across all three browsers in parallel:
- Chromium, Firefox, WebKit via matrix strategy
- Test reports uploaded as artifacts
- Screenshots captured and uploaded on failure
golangci-lintfor code quality