Skip to content

Commit

Permalink
add playwright e2e tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusFelling committed Sep 16, 2022
1 parent 26342db commit 078fd0e
Show file tree
Hide file tree
Showing 12 changed files with 331 additions and 5 deletions.
47 changes: 42 additions & 5 deletions .github/workflows/podcast-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ env:

jobs:
build:
environment:
environment:
name: prod
runs-on: ubuntu-latest

Expand Down Expand Up @@ -53,10 +53,10 @@ jobs:
- name: Set Blazor WASM app settings
uses: microsoft/variable-substitution@v1
with:
files: 'src/Web/Client/wwwroot/appsettings.json'
files: "src/Web/Client/wwwroot/appsettings.json"
env:
PodcastApi.BaseAddress: ${{ env.PODCAST_API_URL }}
ListenTogetherHub: ${{ env.LISTEN_TOGETHER_HUB_URL }}
ListenTogetherHub: ${{ env.LISTEN_TOGETHER_HUB_URL }}

- name: Build
run: dotnet build src/Web/Server --configuration Release
Expand All @@ -75,7 +75,7 @@ jobs:

deploy:
needs: build
environment:
environment:
name: prod
if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch') }}
runs-on: ubuntu-latest
Expand All @@ -98,7 +98,7 @@ jobs:
with:
name: drop
path: web

- name: Update App Service app settings variables
uses: Azure/appservice-settings@v1
with:
Expand All @@ -120,3 +120,40 @@ jobs:
with:
app-name: ${{ secrets.WEBAPP_NAME }}
package: web

test:
needs: deploy
timeout-minutes: 60
runs-on: ubuntu-latest
container: mcr.microsoft.com/playwright:v1.25.2-focal
env:
BASEURL: https://${{secrets.WEBAPP_NAME}}.azurewebsites.net # sets value for URL to test
defaults:
run:
working-directory: src/Web/E2E
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14.x"

- name: Install dependencies
run: npm ci

- name: Run Playwright tests
run: |
HOME=/root npx playwright test
- name: Create test summary
uses: test-summary/action@dist
if: always()
with:
paths: src/Web/E2E/test-results/junit.xml

- name: Upload HTML report
uses: actions/upload-artifact@v2
if: always()
with:
name: playwright-report
path: src/Web/E2E/playwright-report/
retention-days: 30
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,8 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
*.DS_Store

# Playwright tests
src/Web/E2E/test-results/
src/Web/E2E/playwright-report/
src/Web/E2E/playwright/.cache/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ products:
- azure-container-apps
- azure-container-registry
- azure-app-service-web
- playwright
---

# .NET Podcasts - Sample Application
Expand Down
74 changes: 74 additions & 0 deletions src/Web/E2E/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions src/Web/E2E/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "dotnet-podcasts",
"version": "1.0.0",
"description": "---\r page_type: sample\r description: \".NET 6 reference application shown at .NET Conf 2021 featuring ASP.NET Core, Blazor, .NET MAUI, Microservices, and more!\"\r languages:\r - csharp\r products:\r - dotnet-core\r - ef-core\r - blazor\r - dotnet-maui\r - azure-sql-database\r - azure-storage\r - azure-container-apps\r - azure-container-registry\r - azure-app-service-web\r ---",
"main": "index.js",
"directories": {
"doc": "docs"
},
"scripts": {},
"repository": {
"type": "git",
"url": "git+https://github.com/Microsoft/dotnet-podcasts.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/Microsoft/dotnet-podcasts/issues"
},
"homepage": "https://github.com/Microsoft/dotnet-podcasts#readme",
"devDependencies": {
"@playwright/test": "^1.25.2"
}
}
59 changes: 59 additions & 0 deletions src/Web/E2E/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { PlaywrightTestConfig } from '@playwright/test';
import { devices } from '@playwright/test';

const config: PlaywrightTestConfig = {
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,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [
['html'],
['junit', { outputFile: './test-results/junit.xml' }],
],
/* 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: process.env.BASEURL,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on',
video: 'on',
},

projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'firefox',
use: {
...devices['Desktop Firefox'],
},
},
{
name: 'webkit',
use: {
...devices['Desktop Safari'],
},
},
],
};

export default config;
31 changes: 31 additions & 0 deletions src/Web/E2E/tests/discover.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { test, expect, Page } from '@playwright/test';

test.describe.configure({ mode: 'parallel' });

test.beforeEach(async ({ page }) => {
await page.goto('/discover');
});

test.describe('Discover', () => {
test('should allow me to browse categories', async ({ page }) => {
// Loop through each category
for (const category of ['Microsoft', 'Mobile', 'Community', 'M365']) {
// click on the category
await page.locator('.tags-item >> text=' + category).click();
// assert category is selected
await expect(page.locator('.titlePage')).toHaveText(category);
// navigate back to discover page
await page.locator('button:has-text("Back")').click();
}
});

test('should allow me to search', async ({ page }) => {
// use search bar
await page.locator('[placeholder="Search here"]').click();
// search for a podcast
await page.locator('[placeholder="Search here"]').fill('.NET');
await page.locator('[placeholder="Search here"]').press('Enter');
// assert no results page isn't shown
expect(page.locator('.main')).not.toContain('no results');
});
});
19 changes: 19 additions & 0 deletions src/Web/E2E/tests/listen-later.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test, expect, Page } from '@playwright/test';

test.beforeEach(async ({ page }) => {
await page.goto('/discover');
});

test.describe('Listen Later', () => {
test('should allow me to listen to podcast later', async ({ page }) => {
// click first podcast in list
await page.locator('.item-primary-action').first().click();
// click first listen later button
await page.locator('button.buttonIcon.episode-actions-later').first().click();
// view listen later tab
await page.locator('.navbarApp-item >> text=ListenLater').click();
await expect(page).toHaveURL('/listen-later');
// assert no results page isn't shown
expect(page.locator('.main')).not.toContain('no results');
});
});
26 changes: 26 additions & 0 deletions src/Web/E2E/tests/listen-together.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { test, expect, Page } from '@playwright/test';

test.beforeEach(async ({ page }) => {
await page.goto('/discover');
});

test.describe('Listen Together', () => {
test('should allow me to listen together', async ({ page }) => {
// click first podcast in list
await page.locator('.item-primary-action').first().click();
// click play
await page.locator('.icon-play').first().click();
// click go to listen together page
await page.locator('text=ListenTogether').click();
await expect(page).toHaveURL('/listen-together');
// assert Create new room button isn't disabled
expect(page.locator('.buttonApp.primary >> text=Create new room')).toBeEnabled
// create new room
await page.locator('.buttonApp.primary >> text=Create new room').click();
await page.locator('[placeholder="Your name"]').fill('test');
// open room
await page.locator('button:has-text("Open room")').click();
// leave the room
await page.locator('text=Leave the room').click();
});
});
15 changes: 15 additions & 0 deletions src/Web/E2E/tests/login.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { test, expect, Page } from '@playwright/test';

test.beforeEach(async ({ page }) => {
await page.goto('');
});

test.describe('Login', () => {
test('should allow me to login', async ({ page }) => {
// click sign in
await page.locator('text=Sign In').click();
// assert discover page is shown
await expect(page).toHaveURL('/discover');
expect(page).toHaveTitle('.NET Podcasts')
});
});
16 changes: 16 additions & 0 deletions src/Web/E2E/tests/settings.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { test, expect, Page } from '@playwright/test';

test.beforeEach(async ({ page }) => {
await page.goto('/settings');
});

test.describe('Settings', () => {
test('should allow me to toggle settings', async ({ page }) => {
// loop through each setting
for (const setting of ['autodownload', 'deleteplayed', 'systemtheme', 'darktheme']) {
// toggle setting
await page.locator('input[name="' + setting + '"]').check();
await page.locator('input[name="' + setting + '"]').uncheck();
}
});
});
19 changes: 19 additions & 0 deletions src/Web/E2E/tests/subscriptions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test, expect, Page } from '@playwright/test';

test.beforeEach(async ({ page }) => {
await page.goto('/discover');
});

test.describe('Subscriptions', () => {
test('should allow me to subscribe', async ({ page }) => {
// click first podcast in list
await page.locator('.item-primary-action').first().click();
// click subscribe
await page.locator('button:has-text("Subscribe")').click();
// view subscriptions
await page.locator('.navbarApp-item >> text=subscriptions').click();
await expect(page).toHaveURL('/subscriptions');
// assert subscriptions are shown
expect(page.locator('.main')).not.toContain('You haven’t subscribed to any channel yet.');
});
});

0 comments on commit 078fd0e

Please sign in to comment.