-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #444 from ynput/432-Testing-Setup-Playwright-end-t…
…o-end-testing-and-write-first-tests Testing: setup playwright and first basic end to end tests
- Loading branch information
Showing
19 changed files
with
519 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// @ts-check | ||
const { defineConfig, devices } = require('@playwright/test') | ||
|
||
/** | ||
* Read environment variables from file. | ||
* https://github.com/motdotla/dotenv | ||
*/ | ||
require('dotenv').config({ path: ['.env.local'] }) | ||
|
||
/** | ||
* @see https://playwright.dev/docs/test-configuration | ||
*/ | ||
module.exports = defineConfig({ | ||
testDir: './tests', | ||
/* 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: { | ||
/* Base URL to use in actions like `await page.goto('/')`. */ | ||
baseURL: process.env.LOCAL_SERVER_URL, | ||
|
||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||
trace: 'on-first-retry', | ||
}, | ||
|
||
/* Configure projects for major browsers */ | ||
projects: [ | ||
// Setup project | ||
{ name: 'setup', testMatch: /.*\.setup\.js/ }, | ||
{ | ||
name: 'chromium', | ||
use: { | ||
...devices['Desktop Chrome'], // Use prepared auth state. | ||
storageState: 'playwright/.auth/user.json', | ||
}, | ||
dependencies: ['setup'], | ||
}, | ||
|
||
{ | ||
name: 'firefox', | ||
use: { | ||
...devices['Desktop Firefox'], // Use prepared auth state. | ||
storageState: 'playwright/.auth/user.json', | ||
}, | ||
dependencies: ['setup'], | ||
}, | ||
|
||
{ | ||
name: 'webkit', | ||
use: { | ||
...devices['Desktop Safari'], // Use prepared auth state. | ||
storageState: 'playwright/.auth/user.json', | ||
}, | ||
dependencies: ['setup'], | ||
}, | ||
|
||
/* 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: { ...devices['Desktop Edge'], channel: 'msedge' }, | ||
// }, | ||
// { | ||
// name: 'Google Chrome', | ||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' }, | ||
// }, | ||
], | ||
|
||
/* Run your local dev server before starting the tests */ | ||
webServer: { | ||
command: 'yarn dev', | ||
url: process.env.LOCAL_SERVER_URL, | ||
reuseExistingServer: !process.env.CI, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { test as setup } from '@playwright/test' | ||
|
||
const authFile = 'playwright/.auth/user.json' | ||
|
||
setup('authenticate', async ({ page }) => { | ||
await page.goto(process.env.LOCAL_SERVER_URL); | ||
console.log('USERNAME:', process.env.NAME) | ||
// Perform authentication steps. Replace these actions with your own. | ||
await page.getByLabel('Username').fill(process.env.NAME) | ||
await page.getByLabel('Password').fill(process.env.PASSWORD) | ||
await page.getByRole('button', { name: 'Login', exact: true }).click() | ||
// Wait until the page receives the cookies. | ||
// | ||
// Sometimes login flow sets cookies in the process of several redirects. | ||
// Wait for the final URL to ensure that the cookies are actually set. | ||
await page.waitForURL('/dashboard/tasks') | ||
|
||
// End of authentication steps. | ||
|
||
await page.context().storageState({ path: authFile }) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { authenticationTest as test} from './fixtures/authenticationPage' | ||
|
||
test.use({ storageState: { cookies: [], origins: [] } }) | ||
|
||
test('login/logout user', async ({authenticationPage, browserName}) => { | ||
await authenticationPage.login(process.env.NAME!, process.env.PASSWORD!) | ||
await authenticationPage.logout() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { getBundleName, bundleTest as test} from './fixtures/bundlePage' | ||
|
||
test('create/delete bundle', async ({bundlePage, browserName}) => { | ||
const bundleName= getBundleName('test_bundle')(browserName) | ||
await bundlePage.createBundle(bundleName) | ||
await bundlePage.deleteBundle(bundleName) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import {expect, test as base } from '@playwright/test' | ||
import type {Page } from '@playwright/test' | ||
|
||
class AuthenticationPage { | ||
constructor( | ||
public readonly page: Page, | ||
public readonly browserName: String, | ||
) {} | ||
|
||
async goto() { | ||
await this.page.goto('/') | ||
} | ||
async waitForNextPage() { | ||
await this.page.waitForURL('/dashboard/tasks') | ||
} | ||
|
||
async login(username: string, password: string) { | ||
await this.goto() | ||
|
||
// Perform authentication steps. Replace these actions with your own. | ||
await this.page.getByLabel('Username').fill(username) | ||
await this.page.getByLabel('Password').fill(password) | ||
await this.page.getByRole('button', { name: 'Login', exact: true }).click() | ||
await this.waitForNextPage() | ||
} | ||
|
||
async logout() { | ||
// await this.page.getByLabel('Username').fill(process.env.NAME) | ||
// await this.page.getByLabel('Password').fill(process.env.PASSWORD) | ||
// await this.page.getByRole('button', { name: 'Login', exact: true }).click() | ||
// await this.page.waitForURL('/dashboard/tasks') | ||
|
||
await this.page.getByLabel('User menu').click() | ||
await this.page.getByText('Sign out').click() | ||
await expect(this.page).toHaveURL('/login') | ||
} | ||
} | ||
|
||
const test = base.extend<{ authenticationPage: AuthenticationPage }>({ | ||
authenticationPage : async ({ page, browserName }, use) => { | ||
const authenticationPage = new AuthenticationPage(page, browserName); | ||
await use(authenticationPage); | ||
}, | ||
}); | ||
|
||
export default AuthenticationPage | ||
export { test as authenticationTest } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import {expect, test as base } from '@playwright/test' | ||
import type {Page } from '@playwright/test' | ||
|
||
const getBundleName = prefix => browser => prefix + '_' + browser | ||
|
||
class BundlePage { | ||
constructor( | ||
public readonly page: Page, | ||
public readonly browserName: String, | ||
) {} | ||
|
||
async goto() { | ||
await this.page.goto('/settings/bundles') | ||
} | ||
|
||
async createBundle(name: string) { | ||
await this.goto() | ||
await this.page.goto('/settings/bundles') | ||
await this.page.getByRole('button', { name: 'add Add Bundle' }).click() | ||
await this.page.getByRole('main').getByRole('textbox').fill(name) | ||
await this.page.getByRole('button', { name: 'Select an option...' }).click() | ||
const launcher = '1.0.2' | ||
await this.page.getByText(launcher).click() | ||
await this.page.getByRole('button', { name: 'check Create new bundle' }).click() | ||
await expect(this.page.getByText('Bundle created')).toBeVisible() | ||
await expect(this.page.getByRole('cell', { name })).toBeVisible() | ||
|
||
} | ||
|
||
async deleteBundle(name) { | ||
await this.goto() | ||
await this.page.getByRole('cell', { name}).click({ button: 'right' }) | ||
await this.page.getByRole('menuitem', { name: 'archive Archive' }).click() | ||
await this.page.getByRole('cell', { name: `${name} (archived)` }).click({ button: 'right' }) | ||
await this.page.getByRole('menuitem', { name: 'delete Delete' }).click() | ||
await this.page.getByLabel('Delete', { exact: true }).click() | ||
await expect(this.page.getByText('bundles deleted')).toBeVisible() | ||
await expect(this.page.getByRole('cell', { name })).toBeHidden() | ||
} | ||
} | ||
|
||
const test = base.extend<{ bundlePage: BundlePage }>({ | ||
bundlePage: async ({ page, browserName }, use) => { | ||
const projectPage = new BundlePage(page, browserName); | ||
await use(projectPage); | ||
}, | ||
}); | ||
|
||
export default BundlePage | ||
export { getBundleName, test as bundleTest } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { expect, test as base } from '@playwright/test' | ||
import type { Page } from '@playwright/test' | ||
|
||
const getFolderName = prefix => browser => prefix + '_' + browser | ||
|
||
class FolderPage { | ||
constructor( | ||
public readonly page: Page, | ||
public readonly browserName: String, | ||
) {} | ||
|
||
async goto(projectName) { | ||
await this.page.goto(`/projects/${projectName}/editor`) | ||
} | ||
|
||
async createFolder(projectName, folderName) { | ||
await this.goto(projectName) | ||
await this.page.getByRole('button', { name: 'create_new_folder Add Folders' }).click() | ||
await expect(this.page.getByText('add new root folder')).toBeVisible() | ||
await this.page.locator('li[data-value="Folder"]').click() | ||
await this.page.locator('input[value="Folder"]').fill(folderName) | ||
await this.page.getByRole('button', { name: 'check Add and Close' }).click() | ||
await expect(this.page.getByRole('cell', { name: folderName })).toBeVisible() | ||
await this.page.getByRole('button', { name: 'check Save Changes' }).click() | ||
await this.page.getByText('Changes saved').click() | ||
} | ||
|
||
async deleteFolder(projectName, folderName) { | ||
await this.goto(projectName) | ||
await expect(this.page.getByRole('cell', { name: folderName })).toBeVisible() | ||
await this.page.getByRole('cell', { name: folderName }).click({ button: 'right' }) | ||
await this.page.getByRole('menuitem', { name: 'delete Delete' }).click() | ||
await this.page.getByRole('button', { name: 'check Save Changes' }).click() | ||
await this.page.getByText('Changes saved').click() | ||
await expect(this.page.getByRole('cell', { name: folderName })).toBeHidden() | ||
} | ||
} | ||
|
||
const test = base.extend<{ folderPage: FolderPage }>({ | ||
folderPage: async ({ page, browserName }, use) => { | ||
const folderPage = new FolderPage(page, browserName) | ||
await use(folderPage) | ||
}, | ||
}) | ||
|
||
export default FolderPage | ||
|
||
export { getFolderName, test as folderTest } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import {expect, test as base } from '@playwright/test' | ||
import type {Page } from '@playwright/test' | ||
|
||
const getProjectName = prefix => browser => prefix + '_' + browser | ||
|
||
class ProjectPage { | ||
constructor( | ||
public readonly page: Page, | ||
public readonly browserName: String, | ||
) {} | ||
|
||
async goto() { | ||
await this.page.goto('/manageProjects') | ||
} | ||
|
||
async createProject(name: string) { | ||
await this.goto() | ||
await this.page.getByRole('button', { name: 'create_new_folder Add New' }).click() | ||
await this.page.getByPlaceholder('Project Name').fill(name) | ||
await expect(this.page.getByRole('heading', { name: 'Roots' }).nth(1)).toBeVisible() | ||
await this.page.getByRole('button', { name: 'check Create Project' }).click() | ||
await this.page.getByText('Project created').click() | ||
await expect(this.page.getByRole('row', { name: name })).toBeVisible() | ||
} | ||
|
||
async deleteProject(name) { | ||
await this.page.goto('/manageProjects') | ||
const projectCell = await this.page.getByRole('cell', { name }) | ||
const projectCellText = await this.page.getByText(name, { exact: true }) | ||
await projectCell.click({ button: 'right' }) | ||
await this.page.getByRole('menuitem', { name: 'archive Deactivate Project' }).click() | ||
await expect(projectCellText).toHaveCSS('font-style', 'italic') | ||
await projectCell.click({ button: 'right' }) | ||
await this.page.getByRole('menuitem', { name: 'delete Delete Project' }).click() | ||
await this.page.getByLabel('Delete', { exact: true }).click() | ||
await expect(this.page.getByText(`Project: ${name} deleted`)).toBeVisible() | ||
await expect(this.page.getByRole('cell', { name })).toBeHidden() | ||
} | ||
} | ||
|
||
const test = base.extend<{ projectPage: ProjectPage }>({ | ||
projectPage: async ({ page, browserName }, use) => { | ||
const projectPage = new ProjectPage(page, browserName); | ||
await use(projectPage); | ||
}, | ||
}); | ||
|
||
export default ProjectPage | ||
export { getProjectName, test as projectTest } |
Oops, something went wrong.