Skip to content

Commit

Permalink
working tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
AnalogJ committed May 30, 2024
1 parent bec8529 commit 1d52e8f
Show file tree
Hide file tree
Showing 12 changed files with 526 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@

js/dist
js/node_modules

js/local.log
js/playwright-report
js/test-results
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,10 @@ ones that Fasten supports
| [clients/internal/source](./clients/internal/source) | Automatically created OAuth clients for accessing production data from various healthcare institutions. Usually inherit from Platform clients |
| [definitions](./definitions/) | Automatically created definition files. These files are generated from files created by `fasten-sources-gen` and are used by Fasten Lighthouse. |



# References

## NPM Library
- https://www.tsmean.com/articles/learn-typescript/typescript-module-compiler-option/
-
52 changes: 52 additions & 0 deletions js/e2e/browserstack.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import * as cp from 'child_process';
const clientPlaywrightVersion = cp
.execSync('npx playwright --version')
.toString()
.trim()
.split(' ')[1];
import * as BrowserStackLocal from'browserstack-local';
import * as util from'util';
import process from 'process';

// BrowserStack Specific Capabilities.
// Set 'browserstack.local:true For Local testing
const caps = {
browser: 'chrome',
os: 'osx',
os_version: 'catalina',
name: 'My first playwright test',
build: 'playwright-build',
'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'USERNAME',
'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'ACCESSKEY',
'browserstack.local': process.env.BROWSERSTACK_LOCAL || true,
'client.playwrightVersion': clientPlaywrightVersion,
};

export const bsLocal = new BrowserStackLocal.Local();

// replace YOUR_ACCESS_KEY with your key. You can also set an environment variable - "BROWSERSTACK_ACCESS_KEY".
export const BS_LOCAL_ARGS = {
key: process.env.BROWSERSTACK_ACCESS_KEY || 'ACCESSKEY',
};

// Patching the capabilities dynamically according to the project name.
const patchCaps = (name, title) => {
let combination = name.split(/@browserstack/)[0];
let [browerCaps, osCaps] = combination.split(/:/);
let [browser, browser_version] = browerCaps.split(/@/);
let osCapsSplit = osCaps.split(/ /);
let os = osCapsSplit.shift();
let os_version = osCapsSplit.join(' ');
caps.browser = browser ? browser : 'chrome';
caps.os_version = browser_version ? browser_version : 'latest';
caps.os = os ? os : 'osx';
caps.os_version = os_version ? os_version : 'catalina';
caps.name = title;
};

export function getCdpEndpoint(name, title){
patchCaps(name, title)
const cdpUrl = `wss:https://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`
console.log(`--> ${cdpUrl}`)
return cdpUrl;
}
25 changes: 25 additions & 0 deletions js/e2e/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// global-setup.js
import { bsLocal, BS_LOCAL_ARGS } from './browserstack.config';
import { promisify } from 'util';
const sleep = promisify(setTimeout);
const redColour = '\x1b[31m';
const whiteColour = '\x1b[0m';

export default async function setup() {
console.log('Starting BrowserStackLocal ...');
// Starts the Local instance with the required arguments
let localResponseReceived = false;
bsLocal.start(BS_LOCAL_ARGS, (err) => {
if (err) {
console.error(
`${redColour}Error starting BrowserStackLocal${whiteColour}`
);
} else {
console.log('BrowserStackLocal Started');
}
localResponseReceived = true;
});
while (!localResponseReceived) {
await sleep(1000);
}
};
18 changes: 18 additions & 0 deletions js/e2e/global-teardown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// global-teardown.js
import { bsLocal } from './browserstack.config';
import { promisify } from'util';
const sleep = promisify(setTimeout);
export default async function teardown(){
// Stop the Local instance after your test run is completed, i.e after driver.quit
let localStopped = false;

if (bsLocal && bsLocal.isRunning()) {
bsLocal.stop(() => {
localStopped = true;
console.log('Stopped BrowserStackLocal');
});
while (!localStopped) {
await sleep(1000);
}
}
}
32 changes: 32 additions & 0 deletions js/e2e/protractor.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const { SpecReporter } = require('jasmine-spec-reporter');

/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
baseUrl: 'http:https://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
22 changes: 22 additions & 0 deletions js/e2e/src/local_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @ts-check
import { test, expect } from'@playwright/test';

test('Local Testing', async ({ page },testInfo) => {

try{

await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.project.name}})}`);

await page.waitForTimeout(5000);

await page.goto('https://www.example.com/');

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Local success'}})}`);

} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Local fail'}})}`);

}

});
40 changes: 40 additions & 0 deletions js/e2e/src/sample_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// @ts-check
import { test, expect } from'@playwright/test';

test('BstackDemo Add to cart', async ({ page },testInfo) => {

try{

await page.evaluate(_ => {},`browserstack_executor: ${JSON.stringify({action: "setSessionName", arguments: {name:testInfo.project.name}})}`);
await page.waitForTimeout(5000);

await page.goto('https://www.bstackdemo.com/',{ waitUntil: 'networkidle' });
await page.locator('[id="\\32 "]').getByText('Add to cart').click();
await page.getByText('Checkout').click();
await page.locator('#username svg').click();
await page.locator('#react-select-2-option-0-0').click();
await page.locator('#password svg').click();
await page.locator('#react-select-3-option-0-0').click();
await page.getByRole('button', { name: 'Log In' }).click();
await page.getByLabel('First Name').click();
await page.getByLabel('First Name').fill('SampleFirst');
await page.getByLabel('Last Name').click();
await page.getByLabel('Last Name').fill('sampleLast');
await page.getByLabel('Address').click();
await page.getByLabel('Address').fill('sampleAddress');
await page.getByLabel('State/Province').click();
await page.getByLabel('State/Province').fill('SampleState');
await page.getByLabel('Postal Code').click();
await page.getByLabel('Postal Code').fill('123456');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('button', { name: 'Continue Shopping »' }).click();

await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'passed',reason: 'Product added to cart'}})}`);

} catch (e) {
console.log(e);
await page.evaluate(_ => {}, `browserstack_executor: ${JSON.stringify({action: 'setSessionStatus',arguments: {status: 'failed',reason: 'Test failed'}})}`);

}

});
13 changes: 13 additions & 0 deletions js/e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2020",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
8 changes: 7 additions & 1 deletion js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"e2e": "npx playwright test"
},
"author": "Jason Kulatunga <[email protected]>",
"dependencies": {
"@panva/oauth4webapi": "1.2.0"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@playwright/test": "^1.44.1",
"browserstack-local": "^1.5.5",
"typescript": "^5.4.5"
}
}
85 changes: 85 additions & 0 deletions js/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// @ts-check
import { devices } from'@playwright/test';
import { getCdpEndpoint } from './e2e/browserstack.config.ts'
import process from 'process';
import * as path from 'path';

/**
* 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}
*/
export default {
testDir: './e2e/src',
testMatch: '**/*.ts',

globalSetup: path.join( path.dirname("."), 'e2e/global-setup.ts'),
globalTeardown: path.join( path.dirname("."),'./e2e/global-teardown.ts'),

/* Maximum time one test can run for. */
timeout: 90 * 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:https://localhost:3000',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
},

/* Configure projects for major browsers */
projects: [
{
name: 'chrome@latest:Windows 11',
use: {
connectOptions: { wsEndpoint: getCdpEndpoint('chrome@latest:Windows 11','test1') },
},
}
// {
// name: 'playwright-webkit@latest:OSX Ventura',
// use: {
// connectOptions: { wsEndpoint: getCdpEndpoint('playwright-webkit@latest:OSX Ventura', 'test2') }
// },
// },
// {
// name: 'playwright-firefox:Windows 11',
// use: {
// connectOptions: { wsEndpoint: getCdpEndpoint('playwright-firefox:Windows 11', 'test3') }
// },
// }
],

/* 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 start',
// port: 3000,
// },
};

0 comments on commit 1d52e8f

Please sign in to comment.