From dc68d511bd5d01306ca364051c1209c0fe7ab89a Mon Sep 17 00:00:00 2001 From: depa panjie purnama Date: Tue, 25 Oct 2022 02:12:53 +0700 Subject: [PATCH] add e2e test using playwright (#44) --- .github/workflows/playwright.yml | 27 ++++++++ .gitignore | 3 + package.json | 5 +- playwright.config.js | 109 +++++++++++++++++++++++++++++++ tests/home.spec.js | 34 ++++++++++ tests/pages/home.page.js | 50 ++++++++++++++ 6 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 playwright.config.js create mode 100644 tests/home.spec.js create mode 100644 tests/pages/home.page.js diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 000000000..badbde6cc --- /dev/null +++ b/.github/workflows/playwright.yml @@ -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 diff --git a/.gitignore b/.gitignore index 897f90953..33e25480b 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ yarn-error.log* /renderer /renderer/.next/ /renderer/out/ +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/package.json b/package.json index 6354d5198..72dc159ec 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "packages/bruno-testbench" ], "devDependencies": { + "@playwright/test": "^1.27.1", "jest": "^29.2.0", "randomstring": "^1.2.2" }, @@ -17,6 +18,8 @@ "build:web": "npm run build --workspace=packages/bruno-app", "dev:electron": "npm run dev --workspace=packages/bruno-electron", "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" } } diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 000000000..fb328c415 --- /dev/null +++ b/playwright.config.js @@ -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; diff --git a/tests/home.spec.js b/tests/home.spec.js new file mode 100644 index 000000000..7509e62b7 --- /dev/null +++ b/tests/home.spec.js @@ -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(); + }); + +}); diff --git a/tests/pages/home.page.js b/tests/pages/home.page.js new file mode 100644 index 000000000..abcfc9df4 --- /dev/null +++ b/tests/pages/home.page.js @@ -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(); + } +}