Skip to content

Commit 3df93fe

Browse files
initial commit 🚀
0 parents  commit 3df93fe

File tree

10 files changed

+419
-0
lines changed

10 files changed

+419
-0
lines changed

.github/workflows/playwright.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Playwright Tests
2+
on:
3+
push:
4+
branches: [ main, master ]
5+
pull_request:
6+
branches: [ main, master ]
7+
jobs:
8+
test:
9+
timeout-minutes: 60
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: actions/setup-node@v4
14+
with:
15+
node-version: lts/*
16+
- name: Install dependencies
17+
run: npm ci
18+
- name: Install Playwright Browsers
19+
run: npx playwright install --with-deps
20+
- name: Run Playwright tests
21+
run: npx playwright test
22+
- uses: actions/upload-artifact@v4
23+
if: ${{ !cancelled() }}
24+
with:
25+
name: playwright-report
26+
path: playwright-report/
27+
retention-days: 30

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
# Playwright
3+
node_modules/
4+
/test-results/
5+
/playwright-report/
6+
/blob-report/
7+
/playwright/.cache/

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Page Object Model (POM) Pattern
2+
3+
Este projeto é uma suíte de testes automatizados utilizando [Playwright](https://playwright.dev/) para validar fluxos de autenticação e cadastro em uma aplicação web. O projeto adota o padrão **Page Object Model (POM)** para organizar e simplificar a interação com as páginas, tornando os testes mais legíveis, reutilizáveis e de fácil manutenção.
4+
5+
## Contexto
6+
7+
O objetivo deste repositório é demonstrar como estruturar testes automatizados de ponta a ponta (E2E) utilizando o padrão de projeto **Page Object Model**. Esse padrão encapsula operações e elementos de cada página em classes específicas, expondo métodos de alto nível para os testes, sem que eles precisem conhecer detalhes de implementação dos elementos da interface.
8+
9+
## Sobre o Page Object Model
10+
11+
O **Page Object Model (POM)** é um padrão de design que promove a criação de classes para cada página da aplicação, centralizando os seletores e ações em um único local. Isso facilita a manutenção dos testes, pois mudanças na interface exigem alterações apenas nos objetos de página correspondentes.
12+
13+
**Exemplo:**
14+
```typescript
15+
const loginPage = new LoginPage(page);
16+
await loginPage.login("email@teste.com", "senha");
17+
```
18+
19+
## Estrutura do Projeto
20+
21+
- `ui/pages/`: Page Objects com os elementos e ações de cada página.
22+
- `tests/`: Arquivos de teste automatizados.
23+
- `playwright.config.ts`: Configuração do Playwright (incluindo baseURL).
24+
25+
## Comandos Essenciais
26+
27+
- **Executar todos os testes:**
28+
```
29+
npx playwright test
30+
```
31+
32+
- **Executar testes em modo UI interativo:**
33+
```
34+
npx playwright test --ui
35+
```
36+
37+
- **Executar testes em um navegador específico:**
38+
```
39+
npx playwright test --project=chromium
40+
```
41+
42+
- **Executar um arquivo de teste específico:**
43+
```
44+
npx playwright test tests/login.test.ts
45+
```
46+
47+
- **Executar em modo debug:**
48+
```
49+
npx playwright test --debug
50+
```
51+
52+
- **Gerar testes automaticamente com Codegen:**
53+
```
54+
npx playwright codegen
55+
```
56+
57+
## Requisitos
58+
59+
- Node.js instalado
60+
- Dependências instaladas com:
61+
```
62+
npm install
63+
```
64+
65+
## Observações
66+
67+
- O projeto utiliza `baseURL` configurado no `playwright.config.ts`, permitindo o uso de caminhos relativos nos testes.
68+
- Como a aplicação de exemplo não possui banco de dados persistente, os dados criados existem apenas durante a sessão.

constants/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const BASE_URL = "https://bugbank.netlify.app/";

package-lock.json

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "automation-patterns",
3+
"version": "1.0.0",
4+
"description": "automation test patterns",
5+
"main": "index.js",
6+
"scripts": {},
7+
"author": "Alex Alexandre Alves",
8+
"license": "ISC",
9+
"devDependencies": {
10+
"@playwright/test": "^1.54.0",
11+
"@types/node": "^24.0.13"
12+
}
13+
}

playwright.config.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
/**
4+
* Read environment variables from file.
5+
* https://github.com/motdotla/dotenv
6+
*/
7+
// import dotenv from 'dotenv';
8+
// import path from 'path';
9+
// dotenv.config({ path: path.resolve(__dirname, '.env') });
10+
11+
/**
12+
* See https://playwright.dev/docs/test-configuration.
13+
*/
14+
export default defineConfig({
15+
testDir: './tests',
16+
/* Run tests in files in parallel */
17+
fullyParallel: false,
18+
/* Fail the build on CI if you accidentally left test.only in the source code. */
19+
forbidOnly: !!process.env.CI,
20+
/* Retry on CI only */
21+
retries: process.env.CI ? 2 : 0,
22+
/* Opt out of parallel tests on CI. */
23+
workers: process.env.CI ? 1 : undefined,
24+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
25+
reporter: 'html',
26+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
27+
use: {
28+
/* Base URL to use in actions like `await page.goto('/')`. */
29+
baseURL: 'https://bugbank.netlify.app/',
30+
31+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
32+
trace: 'on-first-retry',
33+
},
34+
35+
/* Configure projects for major browsers */
36+
projects: [
37+
{
38+
name: 'chromium',
39+
use: { ...devices['Desktop Chrome'] },
40+
},
41+
42+
{
43+
name: 'firefox',
44+
use: { ...devices['Desktop Firefox'] },
45+
},
46+
47+
// {
48+
// name: 'webkit',
49+
// use: { ...devices['Desktop Safari'] },
50+
// },
51+
52+
/* Test against mobile viewports. */
53+
// {
54+
// name: 'Mobile Chrome',
55+
// use: { ...devices['Pixel 5'] },
56+
// },
57+
// {
58+
// name: 'Mobile Safari',
59+
// use: { ...devices['iPhone 12'] },
60+
// },
61+
62+
/* Test against branded browsers. */
63+
// {
64+
// name: 'Microsoft Edge',
65+
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
66+
// },
67+
// {
68+
// name: 'Google Chrome',
69+
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
70+
// },
71+
],
72+
73+
/* Run your local dev server before starting the tests */
74+
// webServer: {
75+
// command: 'npm run start',
76+
// url: 'http://localhost:3000',
77+
// reuseExistingServer: !process.env.CI,
78+
// },
79+
});

tests/login.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from '@playwright/test';
3+
import { LoginPage } from '../ui/pages/login-page';
4+
import { RegisterPage } from '../ui/pages/register-page';
5+
6+
7+
test.beforeEach(async ({ page }) => {
8+
await page.goto('/')
9+
})
10+
11+
test.describe('Register and Authentication tests', () => {
12+
13+
test('CT001 - Should be able to create a new user with success', async ({ page }) => {
14+
const loginPage = new LoginPage(page);
15+
const registerPage = new RegisterPage(page);
16+
17+
// Do the registration
18+
await loginPage.clickRegisterButton();
19+
await registerPage.fillEmail("usuarioteste@gmail.com");
20+
await registerPage.fillName("Testezinho da Silva");
21+
await registerPage.fillPassword("12345");
22+
await registerPage.fillPasswordConfirmation("12345");
23+
await registerPage.clickRegisterButton();
24+
25+
// Register confirmation assert
26+
await expect(registerPage.confirmationMessage).toBeVisible();
27+
await expect(registerPage.confirmationIcon).toBeVisible();
28+
await registerPage.closeButton.click();
29+
30+
// Do login at the same flow because the application doesn't have database, so it saves only in memory
31+
await loginPage.fillEmail("usuarioteste@gmail.com");
32+
await loginPage.fillPassword("12345");
33+
await loginPage.clickLoginButton();
34+
await loginPage.page.waitForURL("https://bugbank.netlify.app/home");
35+
await expect(loginPage.page).toHaveURL("https://bugbank.netlify.app/home");
36+
});
37+
});

ui/pages/login-page.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Page, Locator } from "@playwright/test";
2+
3+
4+
export class LoginPage {
5+
6+
readonly page: Page;
7+
readonly emailInput: Locator;
8+
readonly passwordInput: Locator;
9+
readonly loginButton: Locator;
10+
readonly registerButton: Locator;
11+
12+
constructor(page: Page) {
13+
this.page = page;
14+
this.emailInput = page.locator('form').filter({ hasText: 'E-mailSenhaAcessarRegistrarConheça nossos requisitosA aplicação não conta com' }).getByPlaceholder('Informe seu e-mail');
15+
this.passwordInput = page.locator('form').filter({ hasText: 'E-mailSenhaAcessarRegistrarConheça nossos requisitosA aplicação não conta com' }).getByPlaceholder('Informe sua senha');
16+
this.loginButton = page.getByRole('button', { name: 'Acessar' });
17+
this.registerButton = page.getByRole('button', { name: 'Registrar' });
18+
}
19+
20+
async fillEmail(email: string) {
21+
await this.emailInput.fill(email);
22+
}
23+
24+
async fillPassword(password: string) {
25+
await this.passwordInput.fill(password);
26+
}
27+
28+
async clickLoginButton() {
29+
await this.loginButton.click();
30+
}
31+
32+
async clickRegisterButton() {
33+
await this.registerButton.click();
34+
}
35+
36+
}

0 commit comments

Comments
 (0)