Skip to content

Commit

Permalink
Merge pull request #1 from cosmicds/testing
Browse files Browse the repository at this point in the history
Add testing infrastructure
  • Loading branch information
Carifio24 authored Jan 22, 2024
2 parents b282f28 + 6b76ae6 commit 39b6d13
Show file tree
Hide file tree
Showing 12 changed files with 2,325 additions and 77 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Build and Deploy

on:
push:
branches:
main

jobs:
build:
if: ${{ github.repository_owner == 'cosmicds' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18.17.1'

- name: Yarn install
run: yarn install

- name: Lint
run: yarn lint

- name: Build
run: yarn build

- name: BrowserStack env setup
uses: browserstack/github-actions/setup-env@master
with:
username: ${{ secrets.BROWSERSTACK_USERNAME }}
access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}

- name: BrowserStack local tunnel setup
uses: browserstack/github-actions/setup-local@master
with:
local-testing: start
local-identifier: random

- name: Run BrowserStack tests
run: yarn test-bslocal -e default,firefox,edge,safari -o reports

- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: dist
ssh-key: ${{ secrets.DEPLOY_KEY }}
52 changes: 52 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build

on:
pull_request_target:
branches:
main

permissions: read-all

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
persist-credentials: false
ref: ${{ github.event.pull_request.head.sha }}

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18.17.1'

- name: Yarn install
run: yarn install

- name: Lint
run: yarn lint

- name: Build
run: yarn build

- name: BrowserStack env setup
uses: browserstack/github-actions/setup-env@master
with:
username: ${{ secrets.BROWSERSTACK_USERNAME }}
access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}

- name: 'BrowserStack local tunnel setup'
uses: browserstack/github-actions/setup-local@master
with:
local-testing: start
local-identifier: random

- name: Run BrowserStack tests
run: yarn test-bslocal -e default,firefox,edge,safari -o reports

- name: 'BrowserStackLocal Stop' # Terminating the BrowserStackLocal tunnel connection
uses: browserstack/github-actions/setup-local@master
with:
local-testing: stop
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"webpack-plugin-vuetify": "^2.0.0"
},
"devDependencies": {
"@types/nightwatch": "^2.3.30",
"@typescript-eslint/eslint-plugin": "^5.48.1",
"@typescript-eslint/parser": "^5.48.1",
"@typescript-eslint/typescript-estree": "7.0.0-alpha.0",
Expand All @@ -22,17 +23,25 @@
"@vue/cli-service": "^5.0.8",
"@vue/compiler-sfc": "^3.2.45",
"@vue/eslint-config-typescript": "^11.0.2",
"browserstack-local": "^1.5.5",
"chai": "^4.3.7",
"chromedriver": "^120.0.2",
"edgedriver": "^5.3.9",
"eslint": "^8.31.0",
"eslint-plugin-vue": "^9.8.0",
"geckodriver": "^4.3.0",
"less": "^4.2.0",
"less-loader": "^12.1.0",
"nightwatch": "^2.6.16",
"typescript": "latest",
"webpack": "^5.75.0"
},
"scripts": {
"build": "vue-cli-service build",
"clean": "rimraf dist",
"lint": "vue-cli-service lint src --no-fix",
"serve": "vue-cli-service serve"
"serve": "vue-cli-service serve",
"test-local": "cd tests; tsc; nightwatch -c dist/local.conf.js --group tests",
"test-bslocal": "cd tests; tsc; node scripts/bslocal.runner.js -c dist/bslocal.conf.js --group tests"
}
}
90 changes: 90 additions & 0 deletions tests/bslocal.conf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* eslint-disable @typescript-eslint/naming-convention */
// The naming convention for the configuration object doesn't match our project styling
// but the transpiled JS version of this is used as a config file for BrowserStack
// so we're beholden to their formatting in this case

import {
addBrowsers,
browserCapabilities,
Configuration
} from "./config";

// See https://www.browserstack.com/automate/capabilities
const BSLOCAL_CAPABILITIES = {
'browserstack.user': process.env.BROWSERSTACK_USERNAME,
'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
'browserstack.local': true,
'name': 'Bstack-[Nightwatch] Local Test'
};

const localDirectory = __dirname;

const nightwatchConfig: Configuration = {
src_folders: [localDirectory],
page_objects_path: [localDirectory + "/page_objects"],
custom_assertions_path: [],
disable_typescript: true,

selenium : {
"start_process" : false,
"host" : "hub-cloud.browserstack.com",
"port" : 443,

//"proxy": "http://PROXY_USERNAME:PROXY_PASSWORD@proxy-host:proxy-port" // If you are behind a proxy
},

globals_path: '',

test_settings: {
default: {
desiredCapabilities: {
...BSLOCAL_CAPABILITIES,
...browserCapabilities('chrome', 'latest', 'Windows', '10'),
}
}
}
};

// Matrix over OSes/browsers that we want to use
const environments = nightwatchConfig.test_settings;

// Windows
const WINDOWS_VERSIONS = ["10", "8.1", "7"];
const WINDOWS_BROWSERS = ["Chrome", "MicrosoftEdge", "Firefox", "IE"];
const winKeyMaker = function(version: string, browser: string): string {
const browserName = (browser === 'MicrosoftEdge' ? 'Edge' : browser);
return `${browserName}_Win${version}`.replace(" ", "");
};
addBrowsers(environments, BSLOCAL_CAPABILITIES, 'Windows', WINDOWS_VERSIONS, WINDOWS_BROWSERS, winKeyMaker);

// OS X
const OSX_VERSIONS = ["Big Sur", "Catalina", "Mojave"];
const OSX_BROWSERS = ["Chrome", "MicrosoftEdge", "Firefox", "Safari"];
const osxKeyMaker = function(version: string, browser: string): string {
const browserName = (browser === 'MicrosoftEdge' ? 'Edge' : browser);
return `${browserName}_${version}`.replace(" ", "");
};
addBrowsers(environments, BSLOCAL_CAPABILITIES, 'OS X', OSX_VERSIONS, OSX_BROWSERS, osxKeyMaker);

// For convenience, add the latest versions of browsers on Windows
// (except Safari, for which we use OS X)
// to an environment named `<lowercasebrowsername>`
const simpleKeyMaker = function(_version: string, browser: string): string {
if (browser === 'MicrosoftEdge') {
return 'edge';
}
return browser.toLowerCase();
};
addBrowsers(environments, BSLOCAL_CAPABILITIES, 'Windows', ['10'], ['Chrome', 'Firefox', 'MicrosoftEdge'], simpleKeyMaker);
addBrowsers(environments, BSLOCAL_CAPABILITIES, 'OS X', ['Ventura'], ['Safari'], simpleKeyMaker);

// Code to copy seleniumhost/port into test settings
for (const i in nightwatchConfig.test_settings) {
const config = nightwatchConfig.test_settings[i];
if (config === undefined || nightwatchConfig.selenium === undefined) {
continue;
}
config['selenium_host'] = nightwatchConfig.selenium.host;
config['selenium_port'] = nightwatchConfig.selenium.port;
}
module.exports = nightwatchConfig;
98 changes: 98 additions & 0 deletions tests/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* eslint-disable @typescript-eslint/naming-convention */
// The naming convention for these interfaces don't match our project styling
// but it's easier to just match BrowserStack formatting, rather than have
// to do a bunch of key remapping

// The creation of the capabilities is based on
// https://www.browserstack.com/automate/capabilities
export interface SeleniumSettings {
start_process: boolean;
host: string;
port: number;
}

export interface WebDriverSettings {
start_process: boolean;
server_path: string;
host?: string;
port?: number;
cli_args?: { [key: string]: string | undefined };
}

export interface Capabilities {
browserName: string,
}

export interface BrowserCapabilities extends Capabilities {
browserVersion: string,
os: string,
osVersion: string;
}

export interface MobileCapabilities extends Capabilities {
device: string,
realMobile: boolean,
osVersion: string;
}

export interface TestEnvironment {
desiredCapabilities: Capabilities;
selenium_host?: string;
selenium_port?: number;
webdriver?: WebDriverSettings;
}

export interface Configuration {
src_folders: string[],
page_objects_path: string[],
custom_assertions_path: string[],
disable_typescript: boolean,
selenium?: SeleniumSettings,
webdriver?: WebDriverSettings,
globals_path: string,
test_settings: { [env: string]: TestEnvironment | undefined }
}

export function browserCapabilities(browserName: string, browserVersion: string, osName: string, osVersion: string): BrowserCapabilities {
return {
'browserName': browserName,
'browserVersion': browserVersion,
'os': osName,
'osVersion': osVersion,
};
}

export function mobileCapabilities(deviceOS: string, deviceName: string, osVersion: string, realMobile=true): MobileCapabilities {
return {
'device': deviceName,
'osVersion': osVersion,
'realMobile': realMobile,
'browserName': deviceOS, // Seems strange, but this is what BrowserStack shows in their examples
};
}

export function addBrowsers(environments: { [env: string]: TestEnvironment | undefined }, baseCapabilities: object, osName: string, osVersions: string[], browsers: string[], envKeyMaker: (version: string, browser: string) => string) {
for (const version of osVersions) {
for (const browser of browsers) {
const key = envKeyMaker(version, browser);
environments[key] = {
desiredCapabilities: {
...baseCapabilities,
...browserCapabilities(browser, 'latest', osName, version)
}
};
}
}
}

export function addPhones(environments: { [env: string]: TestEnvironment | undefined }, baseCapabilities: object, osType: string, devicesAndVersions: string[][], envKeyMaker: (device: string, osVersion: string) => string, realMobile=true) {
for (const [device, osVersion] of devicesAndVersions) {
const key = envKeyMaker(device, osVersion);
environments[key] = {
desiredCapabilities: {
...baseCapabilities,
...mobileCapabilities(osType, device, osVersion, realMobile)
}
};
}
}
Loading

0 comments on commit 39b6d13

Please sign in to comment.