Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Add automated tests to the project #47

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ jobs:
name: compiled-extension
path: dist/extension

test-extension:
name: Test Extension
runs-on: ubuntu-latest
needs: build-extension

steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

- name: Setup Node.js environment
uses: actions/setup-node@v2.1.4
with:
node-version: "12"

- name: Setup Dependencies
run: npm ci

- name: Build Extension
run: npm run build

- name: Setup display for ChromeDriver
run: |
export DISPLAY=:99
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & #

- name: Test Extension
run: npm run test

build-docs:
name: Build Docs
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
};
11,130 changes: 7,612 additions & 3,518 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,29 @@
"noty": "^3.2.0-beta"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-typescript": "^7.12.7",
"@types/chrome": "0.0.128",
"@types/jest": "^26.0.20",
"@types/selenium-webdriver": "^4.0.11",
"@typescript-eslint/eslint-plugin": "^4.13.0",
"@typescript-eslint/parser": "^4.13.0",
"babel-jest": "^26.6.3",
"bestzip": "^2.1.7",
"chromedriver": "^88.0.0",
"copy-webpack-plugin": "^7.0.0",
"cross-env": "^7.0.3",
"cross-var": "^1.1.0",
"eslint": "^7.18.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.3.1",
"husky": "^4.3.8",
"jest": "^26.6.3",
"lint-staged": "^10.5.3",
"prettier": "^2.2.1",
"rimraf": "^3.0.2",
"selenium-webdriver": "^4.0.0-alpha.8",
"ts-loader": "^8.0.14",
"typescript": "^4.1.3",
"unzipper": "^0.10.11",
Expand All @@ -40,6 +49,7 @@
"scripts": {
"watch": "webpack --config webpack/webpack.dev.js --watch",
"docs": "webpack serve --config webpack/webpack.docs.js",
"prebuild": "npm run clean",
"build": "webpack --config webpack/webpack.prod.js",
"build:docs": "webpack --config webpack/webpack.docs.js",
"clean": "rimraf dist",
Expand All @@ -54,7 +64,8 @@
"get:stellar": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 node ./get-stellar.js",
"postinstall": "npm run get:stellar",
"manifest:update": "node manifest-helper.js",
"postversion": "npm run manifest:update && git add . && git commit -m \"Update manifest.json\""
"postversion": "npm run manifest:update && git add . && git commit -m \"Update manifest.json\"",
"test": "jest"
},
"husky": {
"hooks": {
Expand Down
1 change: 1 addition & 0 deletions src/utilities/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export class Overlay {
);
this.wrapper.setAttribute("role", "dialog");
this.wrapper.setAttribute("aria-label", "Robinhood Mint Sync");
this.wrapper.setAttribute("id", "robinhood-mint-sync-overlay");
};

constructor(headerText: string, messageText: string) {
Expand Down
7 changes: 7 additions & 0 deletions tests/Chrome/Licenses.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { driver, extensionId } from "./Setup";

test("The Licenses page loads", async () => {
await driver.get(`chrome-extension://${extensionId}/html/licenses.html`);
const title = await driver.getTitle();
expect(title).toBe("Robinhood Mint Sync - Licenses");
});
117 changes: 117 additions & 0 deletions tests/Chrome/Settings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { driver, extensionId } from "./Setup";

beforeEach(async () => {
await driver.get(`chrome-extension://${extensionId}/html/settings.html`);
});

test("The Settings page loads", async () => {
const title = await driver.getTitle();
expect(title).toBe("Robinhood Mint Sync - Settings");
});

test("Able to turn on changelog on update", async () => {
// Check that it is disabled by default
let isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-changelogOnUpdate") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(false);

// Enable
await driver.executeScript(() => {
(document.querySelector("#setting-changelogOnUpdate") as HTMLInputElement).click();
});

// Wait a little for the setting to save
await driver.manage().setTimeouts({ implicit: 3000 });

// Reload
await driver.navigate().refresh();

// Check that it was enabled correctly
isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-changelogOnUpdate") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(true);
});

test("Able to turn off triangle fix", async () => {
// Check that it is enabled by default
let isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-fixTriangle") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(true);

// Disable
await driver.executeScript(() => {
(document.querySelector("#setting-fixTriangle") as HTMLInputElement).click();
});

// Wait a little for the setting to save
await driver.manage().setTimeouts({ implicit: 3000 });

// Reload
await driver.navigate().refresh();

// Check that it was disabled correctly
isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-fixTriangle") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(false);
});

test("Able to turn on debug mode", async () => {
// Check that it is disabled by default
let isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-debugMode") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(false);

// Enable
await driver.executeScript(() => {
(document.querySelector("#setting-debugMode") as HTMLInputElement).click();
});

// Wait a little for the setting to save
await driver.manage().setTimeouts({ implicit: 3000 });

// Reload
await driver.navigate().refresh();

// Check that it was enabled correctly
isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-debugMode") as HTMLInputElement).checked;
});
expect(isEnabled).toBe(true);
});

test("Able to manually trigger initial setup", async () => {
const originalWindow = await driver.getWindowHandle();
// Click the button
await driver.executeScript(() => {
(document.querySelector(".button") as HTMLInputElement).click();
});

// Wait for the new window or tab
await driver.wait(async () => (await driver.getAllWindowHandles()).length === 2, 10000);

// Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();

for (const handle of windows) {
if (handle !== originalWindow) {
await driver.switchTo().window(handle);
}
}

// Get the title of the current page
const title = await driver.getTitle();

// Expect the sync page to open
expect(title).toContain("Mint.com");

const overlay = await driver.executeScript(() => {
return (document.querySelector("#robinhood-mint-sync-overlay") as HTMLInputElement).innerText;
});

expect(overlay).toContain("Performing Initial Setup");
});
56 changes: 56 additions & 0 deletions tests/Chrome/Setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Builder, ThenableWebDriver } from "selenium-webdriver";
import * as chrome from "selenium-webdriver/chrome";

export let driver: ThenableWebDriver;
export const extensionId = "nafbjkapffjmimgakdpphielakefjfme";

beforeAll(async () => {
const options = new chrome.Options();
options.addArguments("load-extension=dist/extension");
options.setLoggingPrefs({
browser: "ALL",
});

driver = new Builder().forBrowser("chrome").setChromeOptions(options).build();

// Get a reference to the window the tests will run in
const testWindow = await driver.getWindowHandle();

// Wait for the Welcome window to open
await driver.wait(async () => (await driver.getAllWindowHandles()).length === 2, 10000);

// Find and close the welcome window
const windows = await driver.getAllWindowHandles();
for (const handle of windows) {
if (handle !== testWindow) {
await driver.switchTo().window(handle);
await driver.close();
await driver.switchTo().window(testWindow);
}
}
});

afterAll(async () => {
await driver.quit();
});

export const enableDebugMode = async (): Promise<void> => {
await driver.get(`chrome-extension://${extensionId}/html/settings.html`);

const isEnabled = await driver.executeScript(() => {
return (document.querySelector("#setting-debugMode") as HTMLInputElement).checked;
});

if (!isEnabled) {
// Enable debug mode
await driver.executeScript(() => {
(document.querySelector("#setting-debugMode") as HTMLInputElement).click();
});

// Wait a little for the setting to save
await driver.manage().setTimeouts({ implicit: 3000 });
}
};

// Sometimes selenium is slow
jest.setTimeout(30000);
7 changes: 7 additions & 0 deletions tests/Chrome/Welcome.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { driver, extensionId } from "./Setup";

test("The Welcome page loads", async () => {
await driver.get(`chrome-extension://${extensionId}/html/welcome.html`);
const title = await driver.getTitle();
expect(title).toBe("Robinhood Mint Sync - Welcome");
});
21 changes: 21 additions & 0 deletions tests/Chrome/mint/Main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { logging } from "selenium-webdriver";
import { driver, enableDebugMode } from "../Setup";

// We need debug mode enabled to check the console output
beforeAll(enableDebugMode);

test("The Mint script initializes", async () => {
await driver.get(`https://mint.intuit.com/overview.event`);

const logs = await driver.manage().logs().get(logging.Type.BROWSER);

let foundInitializedMessage = false;

logs.forEach((entry) => {
if (entry.message.includes("[Content](Mint - Main)") && entry.message.includes("initialized")) {
foundInitializedMessage = true;
}
});

expect(foundInitializedMessage).toBe(true);
});
21 changes: 21 additions & 0 deletions tests/Chrome/mint/TriangleFix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { logging } from "selenium-webdriver";
import { driver, enableDebugMode } from "../Setup";

// We need debug mode enabled to check the console output
beforeAll(enableDebugMode);

test("The Mint triangle fix script initializes", async () => {
await driver.get(`https://mint.intuit.com/overview.event`);

const logs = await driver.manage().logs().get(logging.Type.BROWSER);

let foundInitializedMessage = false;

logs.forEach((entry) => {
if (entry.message.includes("[Content](Mint - Triangle Fix)") && entry.message.includes("initialized")) {
foundInitializedMessage = true;
}
});

expect(foundInitializedMessage).toBe(true);
});
31 changes: 31 additions & 0 deletions tests/Chrome/mint/properties/Check.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { logging } from "selenium-webdriver";
import { driver, enableDebugMode } from "../../Setup";

// We need debug mode enabled to check the console output
beforeAll(enableDebugMode);

beforeEach(async () => {
await driver.get(`https://mint.intuit.com/settings.event?filter=property&setupRobinhood=true`);
});

test("The Mint property check script initializes", async () => {
const logs = await driver.manage().logs().get(logging.Type.BROWSER);

let foundInitializedMessage = false;

logs.forEach((entry) => {
if (entry.message.includes("[Content](Mint - Properties - Check)") && entry.message.includes("initialized")) {
foundInitializedMessage = true;
}
});

expect(foundInitializedMessage).toBe(true);
});

test("The page displays an overlay", async () => {
const overlay = await driver.executeScript(() => {
return (document.querySelector("#robinhood-mint-sync-overlay") as HTMLInputElement).innerText;
});

expect(overlay).toContain("Performing Initial Setup");
});
33 changes: 33 additions & 0 deletions tests/Chrome/mint/properties/Create.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { logging } from "selenium-webdriver";
import { driver, enableDebugMode } from "../../Setup";

// We need debug mode enabled to check the console output
beforeAll(enableDebugMode);

const testPropertyName = "TESTPROPERTY";

beforeEach(async () => {
await driver.get(`https://mint.intuit.com/settings.event?filter=property&createProperty=true&property=${testPropertyName}`);
});

test("The Mint property create script initializes", async () => {
const logs = await driver.manage().logs().get(logging.Type.BROWSER);

let foundInitializedMessage = false;

logs.forEach((entry) => {
if (entry.message.includes("[Content](Mint - Properties - Create)") && entry.message.includes("initialized")) {
foundInitializedMessage = true;
}
});

expect(foundInitializedMessage).toBe(true);
});

test("The page displays an overlay", async () => {
const overlay = await driver.executeScript(() => {
return (document.querySelector("#robinhood-mint-sync-overlay") as HTMLInputElement).innerText;
});

expect(overlay).toContain(`Adding Robinhood ${testPropertyName} property to Mint.`);
});
Loading