mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
add e2e test using playwright (#44)
This commit is contained in:
parent
0fceaf6918
commit
dc68d511bd
27
.github/workflows/playwright.yml
vendored
Normal file
27
.github/workflows/playwright.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
name: Playwright Tests
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
timeout-minutes: 60
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Install Playwright Browsers
|
||||||
|
run: npx playwright install --with-deps
|
||||||
|
- name: Run Playwright tests
|
||||||
|
run: npm run test:e2e
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: playwright-report
|
||||||
|
path: playwright-report/
|
||||||
|
retention-days: 30
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,3 +37,6 @@ yarn-error.log*
|
|||||||
/renderer
|
/renderer
|
||||||
/renderer/.next/
|
/renderer/.next/
|
||||||
/renderer/out/
|
/renderer/out/
|
||||||
|
/test-results/
|
||||||
|
/playwright-report/
|
||||||
|
/playwright/.cache/
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"packages/bruno-testbench"
|
"packages/bruno-testbench"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.27.1",
|
||||||
"jest": "^29.2.0",
|
"jest": "^29.2.0",
|
||||||
"randomstring": "^1.2.2"
|
"randomstring": "^1.2.2"
|
||||||
},
|
},
|
||||||
@ -17,6 +18,8 @@
|
|||||||
"build:web": "npm run build --workspace=packages/bruno-app",
|
"build:web": "npm run build --workspace=packages/bruno-app",
|
||||||
"dev:electron": "npm run dev --workspace=packages/bruno-electron",
|
"dev:electron": "npm run dev --workspace=packages/bruno-electron",
|
||||||
"build:chrome-extension": "./scripts/build-chrome-extension.sh",
|
"build:chrome-extension": "./scripts/build-chrome-extension.sh",
|
||||||
"build:electron": "./scripts/build-electron.sh"
|
"build:electron": "./scripts/build-electron.sh",
|
||||||
|
"test:e2e": "npx playwright test",
|
||||||
|
"test:report": "npx playwright show-report"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
109
playwright.config.js
Normal file
109
playwright.config.js
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// @ts-check
|
||||||
|
const { devices } = require('@playwright/test');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read environment variables from file.
|
||||||
|
* https://github.com/motdotla/dotenv
|
||||||
|
*/
|
||||||
|
// require('dotenv').config();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://playwright.dev/docs/test-configuration
|
||||||
|
* @type {import('@playwright/test').PlaywrightTestConfig}
|
||||||
|
*/
|
||||||
|
const config = {
|
||||||
|
testDir: './tests',
|
||||||
|
/* Maximum time one test can run for. */
|
||||||
|
timeout: 30 * 1000,
|
||||||
|
expect: {
|
||||||
|
/**
|
||||||
|
* Maximum time expect() should wait for the condition to be met.
|
||||||
|
* For example in `await expect(locator).toHaveText();`
|
||||||
|
*/
|
||||||
|
timeout: 5000
|
||||||
|
},
|
||||||
|
/* Run tests in files in parallel */
|
||||||
|
fullyParallel: true,
|
||||||
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||||
|
forbidOnly: !!process.env.CI,
|
||||||
|
/* Retry on CI only */
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
/* Opt out of parallel tests on CI. */
|
||||||
|
workers: process.env.CI ? 1 : undefined,
|
||||||
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
|
reporter: 'html',
|
||||||
|
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||||
|
use: {
|
||||||
|
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
|
||||||
|
actionTimeout: 0,
|
||||||
|
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||||
|
baseURL: 'http://localhost:3000',
|
||||||
|
|
||||||
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
|
trace: 'retain-on-failure',
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Configure projects for major browsers */
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: 'chromium',
|
||||||
|
use: {
|
||||||
|
...devices['Desktop Chrome'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'firefox',
|
||||||
|
use: {
|
||||||
|
...devices['Desktop Firefox'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: 'webkit',
|
||||||
|
use: {
|
||||||
|
...devices['Desktop Safari'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Test against mobile viewports. */
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Chrome',
|
||||||
|
// use: {
|
||||||
|
// ...devices['Pixel 5'],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Mobile Safari',
|
||||||
|
// use: {
|
||||||
|
// ...devices['iPhone 12'],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
/* Test against branded browsers. */
|
||||||
|
// {
|
||||||
|
// name: 'Microsoft Edge',
|
||||||
|
// use: {
|
||||||
|
// channel: 'msedge',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// name: 'Google Chrome',
|
||||||
|
// use: {
|
||||||
|
// channel: 'chrome',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
],
|
||||||
|
|
||||||
|
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||||
|
// outputDir: 'test-results/',
|
||||||
|
|
||||||
|
/* Run your local dev server before starting the tests */
|
||||||
|
webServer: {
|
||||||
|
command: 'npm run dev:web',
|
||||||
|
port: 3000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
34
tests/home.spec.js
Normal file
34
tests/home.spec.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
const { HomePage } = require('../tests/pages/home.page');
|
||||||
|
|
||||||
|
test.describe('bruno e2e test', () => {
|
||||||
|
let homePage;
|
||||||
|
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
homePage = new HomePage(page);
|
||||||
|
|
||||||
|
await homePage.open();
|
||||||
|
await expect(page).toHaveURL('/');
|
||||||
|
await expect(page).toHaveTitle(/bruno/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('user should be able to load & use sample collection', async () => {
|
||||||
|
await homePage.loadSampleCollection();
|
||||||
|
|
||||||
|
await homePage.getUsers();
|
||||||
|
await expect(homePage.statusRequestSuccess).toBeVisible();
|
||||||
|
|
||||||
|
await homePage.getSingleUser();
|
||||||
|
await expect(homePage.statusRequestSuccess).toBeVisible();
|
||||||
|
|
||||||
|
await homePage.getUserNotFound();
|
||||||
|
await expect(homePage.statusRequestNotFound).toBeVisible();
|
||||||
|
|
||||||
|
await homePage.createUser();
|
||||||
|
await expect(homePage.statusRequestCreated).toBeVisible();
|
||||||
|
|
||||||
|
await homePage.updateUser();
|
||||||
|
await expect(homePage.statusRequestSuccess).toBeVisible();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
50
tests/pages/home.page.js
Normal file
50
tests/pages/home.page.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
exports.HomePage = class HomePage {
|
||||||
|
constructor(page) {
|
||||||
|
this.page = page;
|
||||||
|
this.loadSampleCollectionSelector = page.getByText('Load Sample Collection');
|
||||||
|
this.sampeCollectionSelector = page.getByText('sample-collection');
|
||||||
|
this.getUsersSelector = page.getByText('Users');
|
||||||
|
this.getSingleUserSelector = page.getByText('Single User');
|
||||||
|
this.getUserNotFoundSelector = page.getByText('User Not Found');
|
||||||
|
this.postCreateSelector = page.getByText('Create');
|
||||||
|
this.putUpdateSelector = page.getByText('Update');
|
||||||
|
this.sendRequestButton = page.locator('div:nth-child(2) > .flex > svg');
|
||||||
|
this.statusRequestSuccess = page.getByText('200 OK');
|
||||||
|
this.statusRequestNotFound = page.getByText('404 Not Found');
|
||||||
|
this.statusRequestCreated = page.getByText('201 Created');
|
||||||
|
}
|
||||||
|
|
||||||
|
async open() {
|
||||||
|
await this.page.goto('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadSampleCollection() {
|
||||||
|
await this.loadSampleCollectionSelector.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUsers() {
|
||||||
|
await this.sampeCollectionSelector.click();
|
||||||
|
await this.getUsersSelector.click();
|
||||||
|
await this.sendRequestButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSingleUser() {
|
||||||
|
await this.getSingleUserSelector.click();
|
||||||
|
await this.sendRequestButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUserNotFound() {
|
||||||
|
await this.getUserNotFoundSelector.click();
|
||||||
|
await this.sendRequestButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async createUser() {
|
||||||
|
await this.postCreateSelector.click();
|
||||||
|
await this.sendRequestButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateUser() {
|
||||||
|
await this.putUpdateSelector.click();
|
||||||
|
await this.sendRequestButton.click();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user