-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EA-1204 sample ts app and tests (#57)
* Initial commit * Add dotenv dependency; add .env to gitignore; get default key and oauth creds from .env file that is not checked in * Add .env.example and info about the .env file in README.md * Use next version in TS sample app; update code to handle changes; update tests; add initialize tests * Remove logging * Actually call initialize() when the button is pressed * Add a test for successful authentication
- Loading branch information
1 parent
a4affe9
commit 8284de0
Showing
34 changed files
with
5,179 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
**/.DS_Store | ||
.idea/** | ||
.idea/** | ||
|
||
node_modules | ||
|
||
playwright-report | ||
|
||
test-results | ||
|
||
.env | ||
|
||
.yalc |
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,27 @@ | ||
# Dockerfile | ||
# Use the official Node.js 21 image. | ||
# https://hub.docker.com/_/node | ||
FROM node:21 | ||
|
||
# Create and change to the app directory. | ||
WORKDIR /usr/src/app | ||
|
||
# Install production dependencies. | ||
RUN apt-get update && apt-get install -y \ | ||
wget \ | ||
unzip \ | ||
libxss1 \ | ||
libappindicator1 \ | ||
libindicator7 \ | ||
libasound2 \ | ||
libnss3 \ | ||
libxtst6 \ | ||
xauth \ | ||
xvfb \ | ||
libgbm-dev \ | ||
--no-install-recommends \ | ||
&& wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ | ||
&& dpkg -i google-chrome-stable_current_amd64.deb; apt-get -fy install | ||
|
||
# Install Playwright and its dependencies | ||
RUN npx playwright install && npx playwright install-deps |
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,14 @@ | ||
{ | ||
"name": "e2e Test Container", | ||
"dockerFile": "Dockerfile", | ||
"forwardPorts": [3000], | ||
"postCreateCommand": "npm install", | ||
"customizations": { | ||
"vscode": { | ||
"extensions": [ | ||
"ms-vscode.vscode-typescript-tslint-plugin", | ||
"dbaeumer.vscode-eslint" | ||
] | ||
} | ||
} | ||
} |
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,2 @@ | ||
VITE_DEFAULT_KEY="" | ||
VITE_DEFAULT_OAUTH_CREDS="" |
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,23 @@ | ||
# b.well TypeScript SDK Sample App | ||
|
||
This is a sample TypeScript Web application meant to be used in testing the b.well TypeScript SDK. | ||
|
||
It is built with react, vite, and material-ui. | ||
|
||
## How to run it | ||
|
||
1. `npm i` (if you haven't run it before) | ||
2. `npm run dev` | ||
|
||
## How to run run the tests | ||
|
||
1. `npm run e2e` | ||
|
||
A .env file will need to be present in this directory. See .env.example for the keys that will need to be supported. | ||
|
||
It is also recommended that you run tests in a container to ensure consistent execution across environments. If you are using VS Code, follow these steps: | ||
|
||
1. Navigate into this folder (bwell-typescript-react) | ||
2. Click the little green button in the lower-left corner of your screen | ||
3. Select "Reopen in container" | ||
4. You are now running in a Docker container. `npm run e2e` should run the tests, and a report will open in your web browser once the tests finish running. |
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,44 @@ | ||
import { Page } from "@playwright/test"; | ||
import config from "./configTypes"; | ||
|
||
class HelloPage { | ||
private readonly page: Page; | ||
|
||
private readonly mainMenuLocator = "#btnMainMenu"; | ||
private readonly helloMenuItemLocator = "#helloMenuItem"; | ||
private readonly helloButtonLocator = "#btnHello"; | ||
private readonly clearButtonLocator = "#btnClear"; | ||
private readonly helloResponseLocator = "#preHelloResponse"; | ||
|
||
constructor(page: Page) { | ||
this.page = page; | ||
} | ||
|
||
async navigate() { | ||
await this.page.goto(config.TEST_APP_URL); | ||
await this.clickMainMenu(); | ||
await this.clickHelloMenuItem(); | ||
} | ||
|
||
async clickMainMenu() { | ||
await this.page.click(this.mainMenuLocator); | ||
} | ||
|
||
async clickHelloMenuItem() { | ||
await this.page.locator(this.helloMenuItemLocator).click(); | ||
} | ||
|
||
async clickHelloButton() { | ||
await this.page.click(this.helloButtonLocator); | ||
} | ||
|
||
async clickClearButton() { | ||
await this.page.click(this.clearButtonLocator); | ||
} | ||
|
||
async getHelloResponse() { | ||
return await this.page.textContent(this.helloResponseLocator); | ||
} | ||
} | ||
|
||
export default HelloPage; |
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 { Page } from "@playwright/test"; | ||
import config from "./configTypes"; | ||
|
||
class InitializePage { | ||
private readonly page: Page; | ||
|
||
public readonly mainMenuLocator = "#btnMainMenu"; | ||
public readonly initializeMenuItemLocator = "#initializeMenuItem"; | ||
public readonly txtKeyLocator = "#txtKey"; | ||
public readonly btnInitializeLocator = "#btnInitialize"; | ||
public readonly txtOauthCredsLocator = "#txtOauthCreds"; | ||
public readonly btnLoginLocator = "#btnLogin"; | ||
|
||
constructor(page: Page) { | ||
this.page = page; | ||
} | ||
|
||
async navigate() { | ||
await this.page.goto(config.TEST_APP_URL); | ||
await this.clickMainMenu(); | ||
await this.clickInitializeMenuItem(); | ||
} | ||
|
||
async clickMainMenu() { | ||
await this.page.click(this.mainMenuLocator); | ||
} | ||
|
||
async clickInitializeMenuItem() { | ||
await this.page.locator(this.initializeMenuItemLocator).click(); | ||
} | ||
|
||
async clickInitializeButton() { | ||
await this.page.click(this.btnInitializeLocator); | ||
} | ||
|
||
async enterClientKey(key: string) { | ||
await this.page.fill(this.txtKeyLocator, key); | ||
} | ||
|
||
async enterOAuthCreds(creds: string) { | ||
await this.page.fill(this.txtOauthCredsLocator, creds); | ||
} | ||
|
||
async clickLoginButton() { | ||
await this.page.click(this.btnLoginLocator); | ||
} | ||
} | ||
|
||
export default InitializePage; |
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 { Page } from 'playwright'; | ||
import config from "./configTypes"; | ||
|
||
export class ShadowPageModel { | ||
private page: Page; | ||
|
||
private readonly mainMenuLocator = "#btnMainMenu"; | ||
private readonly shadowMenuItemLocator = "#shadowMenuItem"; | ||
private readonly cpShadowLocator = "#cpShadow"; | ||
private readonly btnStartSpinnerLocator = "#btnStartSpinner"; | ||
private readonly shadowOuterTextSpanLocator = "#spanOuterText"; | ||
private readonly shadowInnerTextSpanLocator = "#spanInnerText"; | ||
|
||
// Initialize the page object | ||
constructor(page: Page) { | ||
this.page = page; | ||
} | ||
|
||
async navigate() { | ||
await this.page.goto(config.TEST_APP_URL); | ||
await this.clickMainMenu(); | ||
await this.clickShadowMenuItem(); | ||
} | ||
|
||
async clickMainMenu() { | ||
await this.page.click(this.mainMenuLocator); | ||
} | ||
|
||
async clickShadowMenuItem() { | ||
await this.page.locator(this.shadowMenuItemLocator).click(); | ||
} | ||
|
||
async getOuterDivText() { | ||
return await this.page.locator(this.shadowOuterTextSpanLocator).innerText(); | ||
} | ||
|
||
async getInnerDivText() { | ||
return await this.page.locator(this.shadowInnerTextSpanLocator).innerText(); | ||
} | ||
|
||
async startSpinner() { | ||
await this.page.click(this.btnStartSpinnerLocator); | ||
} | ||
|
||
async isSpinnerVisible() { | ||
return await this.page.locator(this.cpShadowLocator).isVisible(); | ||
} | ||
} | ||
|
||
export default ShadowPageModel; |
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,13 @@ | ||
import { Browser, Page } from "playwright"; | ||
|
||
declare global { | ||
const page: Page; | ||
const browser: Browser; | ||
const browserName: string; | ||
} | ||
|
||
const config = { | ||
TEST_APP_URL: "http://localhost:5173", | ||
} | ||
|
||
export default config; |
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 HelloPage from "./HelloPage"; | ||
import { test, expect } from "@playwright/test"; | ||
|
||
test("Hello World", async ({ page }) => { | ||
const helloPage = new HelloPage(page); | ||
await helloPage.navigate(); | ||
|
||
//verify that the response is empty | ||
const helloResponseEmpty = await helloPage.getHelloResponse(); | ||
expect(helloResponseEmpty).toBe(""); | ||
|
||
//click the hello button, check that the box populates as expected | ||
await helloPage.clickHelloButton(); | ||
const helloResponsePopulated = await helloPage.getHelloResponse(); | ||
expect(helloResponsePopulated).toBe("World!"); | ||
|
||
//test the clear button as long as we're in here | ||
await helloPage.clickClearButton(); | ||
const secondEmptyHelloResponse = await helloPage.getHelloResponse(); | ||
expect(secondEmptyHelloResponse).toBe(""); | ||
}); |
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,62 @@ | ||
import InitializePage from "./InitializePage"; | ||
import { test, expect } from "@playwright/test"; | ||
import { config } from 'dotenv'; | ||
|
||
//initialize dotenv so we can access the environment variables | ||
config(); | ||
|
||
const DEFAULT_KEY = process.env.VITE_DEFAULT_KEY ?? ""; | ||
const DEFAULT_OAUTH_CREDS = process.env.VITE_DEFAULT_OAUTH_CREDS ?? ""; | ||
|
||
test("Navigating to the Initialize page works", async ({ page }) => { | ||
//arrange | ||
const initializePage = new InitializePage(page); | ||
|
||
//act | ||
await initializePage.navigate(); | ||
|
||
//assert: page title should be "b.well Typescript SDK Example Web App" | ||
expect(await page.title()).toBe("b.well Typescript SDK Example Web App"); | ||
}); | ||
|
||
test("Initialize page doesn't display OAuth Creds initially", async ({ page }) => { | ||
//arrange | ||
const initializePage = new InitializePage(page); | ||
|
||
//act | ||
await initializePage.navigate(); | ||
|
||
//assert: oauth creds textarea should not be visible | ||
expect(await page.isVisible(initializePage.txtOauthCredsLocator)).toBe(false); | ||
}); | ||
|
||
test("Initialize page displays OAuth Creds after client key is entered", async ({ page }) => { | ||
//arrange | ||
const initializePage = new InitializePage(page); | ||
|
||
//act | ||
await initializePage.navigate(); | ||
await initializePage.enterClientKey(DEFAULT_KEY); | ||
await initializePage.clickInitializeButton(); | ||
|
||
const oauthCredsLocator = await page.waitForSelector(initializePage.txtOauthCredsLocator); | ||
const oauthCredsVisible = await oauthCredsLocator.isVisible(); | ||
|
||
//assert: oauth creds textarea should be visible | ||
expect(oauthCredsVisible).toBe(true); | ||
}); | ||
|
||
test("Entering a valid oauth credential results in success", async ({ page }) => { | ||
//arrange | ||
const initializePage = new InitializePage(page); | ||
|
||
//act | ||
await initializePage.navigate(); | ||
await initializePage.enterClientKey(DEFAULT_KEY); | ||
await initializePage.clickInitializeButton(); | ||
|
||
const oauthCredsLocator = await page.waitForSelector(initializePage.txtOauthCredsLocator); | ||
await oauthCredsLocator.fill(DEFAULT_OAUTH_CREDS); | ||
|
||
await initializePage.clickLoginButton(); | ||
}); |
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,29 @@ | ||
import ShadowPage from "./ShadowPage"; | ||
import { test, expect } from "@playwright/test"; | ||
|
||
test("Spinner starts on page load", async ({ page }) => { | ||
const shadowPage = new ShadowPage(page); | ||
|
||
await shadowPage.navigate(); | ||
|
||
expect(await shadowPage.isSpinnerVisible()).toBe(true); | ||
}); | ||
|
||
test("Spinner stops after 3 seconds", async ({ page }) => { | ||
const shadowPage = new ShadowPage(page); | ||
|
||
await shadowPage.navigate(); | ||
|
||
expect(await shadowPage.isSpinnerVisible()).toBe(true); | ||
await page.waitForTimeout(3000); | ||
expect(await shadowPage.isSpinnerVisible()).toBe(false); | ||
}); | ||
|
||
test("When spinner stops, the shadow component is visible", async ({ page }) => { | ||
const shadowPage = new ShadowPage(page); | ||
|
||
await shadowPage.navigate(); | ||
|
||
expect(await shadowPage.getInnerDivText()).toBe("This is the inner div in the Shadow DOM"); | ||
expect(await shadowPage.getOuterDivText()).toBe("This is the outer div in the Shadow DOM"); | ||
}); |
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,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>b.well Typescript SDK Example Web App</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
Oops, something went wrong.