Skip to content

Commit

Permalink
chore(tests) add test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: David Edler <david.edler@canonical.com>
  • Loading branch information
edlerd committed Feb 16, 2024
1 parent fb0212b commit 92aa46d
Show file tree
Hide file tree
Showing 21 changed files with 1,689 additions and 872 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,6 @@ dist/
/test-results/
/playwright-report/
/playwright/.cache/
/coverage

haproxy-local.cfg
haproxy-local.cfg
14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"license": "LGPL-3.0-only",
"type": "module",
"scripts": {
"clean": "rm -rf node_modules yarn-error.log *.log build/ .jekyll-metadata .bundle playwright-report test-results haproxy-local.cfg",
"clean": "rm -rf node_modules yarn-error.log *.log build/ .jekyll-metadata .bundle playwright-report test-results haproxy-local.cfg coverage",
"build-html": "cp build/ui/index.html build/index.html",
"build": "npx vite build && yarn build-html",
"format-js-eslint": "eslint 'src/**/*.{json,jsx,tsx,ts}' 'tests/**/*.ts' --fix",
"format-js-eslint": "eslintdo 'src/**/*.{json,jsx,tsx,ts}' 'tests/**/*.ts' --fix",
"format-js-prettier": "prettier 'src/**/*.{json,jsx,tsx,ts}' 'tests/**/*.ts' --write",
"format-js": "yarn format-js-eslint && yarn format-js-prettier",
"lint-scss": "stylelint 'src/**/*.scss'",
Expand All @@ -19,7 +19,9 @@
"hooks-remove": "husky uninstall",
"start": "concurrently --kill-others --raw 'vite --host | grep -v 3000' 'yarn serve'",
"serve": "./entrypoint",
"test-js": "vitest --run"
"test-js": "vitest --run",
"test-js-coverage": "vitest --run --coverage",
"test-playwright-coverage": "nyc report --reporter html --temp-dir coverage/playwright --report-dir coverage/playwright-report"
},
"dependencies": {
"@canonical/react-components": "0.50.2",
Expand Down Expand Up @@ -62,15 +64,19 @@
"@typescript-eslint/eslint-plugin": "6.19.0",
"@typescript-eslint/parser": "6.19.0",
"@vitejs/plugin-react": "4.2.1",
"@vitest/coverage-istanbul": "1.2.2",
"autoprefixer": "10.4.16",
"babel-plugin-istanbul": "6.1.1",
"concurrently": "8.2.2",
"convert-source-map": "2.0.0",
"eslint": "8.56.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-react": "7.33.2",
"husky": "8.0.3",
"lint-staged": "15.2.0",
"monaco-editor": "0.45.0",
"nyc": "^15.1.0",
"postcss": "8.4.33",
"postcss-cli": "11.0.0",
"prettier": "3.2.4",
Expand All @@ -81,7 +87,9 @@
"stylelint-prettier": "5.0.0",
"stylelint-scss": "6.0.0",
"typescript": "5.3.3",
"v8-to-istanbul": "9.2.0",
"vite": "4.5.2",
"vite-plugin-istanbul": "5.0.0",
"vite-tsconfig-paths": "4.3.1",
"vitest": "1.2.1"
},
Expand Down
15 changes: 4 additions & 11 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import { devices } from "@playwright/test";
const config: PlaywrightTestConfig = {
testDir: "./tests",
/* Maximum time one test can run for. */
timeout: 120 * 1000,
timeout: 120_000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 120 * 1000,
timeout: 120_000,
},
/* 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 : 3,
/* Opt out of parallel tests. */
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: process.env.CI ? "blob" : "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
Expand All @@ -47,13 +47,6 @@ const config: PlaywrightTestConfig = {
...devices["Desktop Chrome"],
},
},

{
name: "firefox",
use: {
...devices["Desktop Firefox"],
},
},
],
};

Expand Down
80 changes: 80 additions & 0 deletions tests/basefixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import * as fs from "fs";
import * as crypto from "crypto";
import { Page, test as baseTest } from "@playwright/test";
import { fromSource, removeMapFileComments } from "convert-source-map";
import v8ToIstanbul from "v8-to-istanbul";
import {
PlaywrightTestArgs,
PlaywrightTestOptions,
PlaywrightWorkerArgs,
PlaywrightWorkerOptions,
TestType,
} from "playwright/types/test";

const generateUUID = (): string => {
return crypto.randomBytes(16).toString("hex");
};

export const test: TestType<
PlaywrightTestArgs & PlaywrightTestOptions,
PlaywrightWorkerArgs & PlaywrightWorkerOptions
> & {
startCoverage: (page: Page) => Promise<void>;
finishCoverage: (page: Page) => Promise<void>;
} = baseTest;

test.startCoverage = async (page: Page) => {
await page.coverage.startJSCoverage();
};

test.finishCoverage = async (page: Page) => {
const coverage = await page.coverage.stopJSCoverage();
for (const entry of coverage) {
if (entry.url.endsWith(".css")) {
continue;
}
if (entry.url.includes("@vite")) {
continue;
}
if (entry.url.includes("spice")) {
continue;
}
const fileMatcher = entry.url.match(/http(s)*:\/\/.*:8407\/(?<file>.*)/);
if (!fileMatcher?.groups) {
continue;
}
const path = fileMatcher.groups.file;
const source = removeMapFileComments(entry.source);
const sourceMap = fromSource(entry.source);

const converter = v8ToIstanbul(path, 0, {
source,
sourceMap,
});
await converter.load();
converter.applyCoverage(entry.functions);
const istanbulCoverage = converter.toIstanbul();

const uuid = generateUUID();

Object.entries(istanbulCoverage).forEach(([key]) => {
istanbulCoverage[key]["_coverageSchema"] = uuid;
});

const outDir = "coverage/playwright";
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir, { recursive: true });
}
fs.writeFileSync(
`${outDir}/playwright_coverage_${uuid}.json`,
JSON.stringify(istanbulCoverage),
);
/**
* to get coverage report:
* npx playwright test
* yarn test-playwright-coverage
*/
}
};

export const expect = test.expect;
25 changes: 22 additions & 3 deletions tests/cluster.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import { Page, test } from "@playwright/test";
import { test } from "./basefixtures";
import { randomNameSuffix } from "./helpers/name";
import { Page } from "@playwright/test";

test("cluster group create and delete", async ({ page }) => {
let page: Page;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
await test.startCoverage(page);
});

test.afterAll(async () => {
await test.finishCoverage(page);
await page.close();
});

test("cluster group create and delete", async () => {
test.skip(true);
const group = randomGroupName();
await createClusterGroup(page, group);
await deleteClusterGroup(page, group);
});

test("cluster group add and remove members", async ({ page }) => {
test("cluster group add and remove members", async () => {
test.skip(true);
const group = randomGroupName();
const member = await getFirstClusterMember(page);
await createClusterGroup(page, group);
Expand All @@ -28,6 +43,7 @@ export const randomGroupName = (): string => {
};

export const createClusterGroup = async (page: Page, group: string) => {
test.skip(true);
await page.goto("/ui/");
await page.getByRole("link", { name: "Cluster" }).click();
await page.getByRole("button", { name: "All cluster groups" }).click();
Expand All @@ -40,6 +56,7 @@ export const createClusterGroup = async (page: Page, group: string) => {
};

export const deleteClusterGroup = async (page: Page, group: string) => {
test.skip(true);
await page.goto("/ui/");
await page.getByRole("link", { name: "Cluster" }).click();
await page.getByRole("button", { name: "All cluster groups" }).click();
Expand All @@ -55,6 +72,7 @@ export const toggleClusterGroupMember = async (
group: string,
member: string,
) => {
test.skip(true);
await page.goto("/ui/");
await page.getByRole("link", { name: "Cluster" }).click();
await page.getByRole("button", { name: "All cluster groups" }).click();
Expand All @@ -70,6 +88,7 @@ export const toggleClusterGroupMember = async (
};

export const getFirstClusterMember = async (page: Page): Promise<string> => {
test.skip(true);
await page.goto("/ui/");
await page.getByRole("link", { name: "Cluster" }).click();
const firstCellContent = await page.getByRole("cell").first().textContent();
Expand Down
23 changes: 17 additions & 6 deletions tests/devices.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test } from "@playwright/test";
import { test } from "./basefixtures";
import {
deleteProfile,
finishProfileCreation,
Expand All @@ -16,10 +16,21 @@ import {
} from "./helpers/instances";
import { attachVolume, detachVolume } from "./helpers/devices";
import { deleteVolume, randomVolumeName } from "./helpers/storageVolume";
import { Page } from "@playwright/test";

test("instance attach custom volumes and detach inherited volumes", async ({
page,
}) => {
let page: Page;

test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
await test.startCoverage(page);
});

test.afterAll(async () => {
await test.finishCoverage(page);
await page.close();
});

test("instance attach custom volumes and detach inherited volumes", async () => {
const profile = randomProfileName();
const profileVolume = randomVolumeName();
const instanceVolume = randomVolumeName();
Expand Down Expand Up @@ -49,7 +60,7 @@ test("instance attach custom volumes and detach inherited volumes", async ({
await deleteVolume(page, profileVolume);
});

test("profile edit custom volumes", async ({ page }) => {
test("profile edit custom volumes", async () => {
const profile = randomProfileName();
const volume = randomVolumeName();

Expand Down Expand Up @@ -83,7 +94,7 @@ test("profile edit custom volumes", async ({ page }) => {
await deleteVolume(page, volume);
});

test("profile edit networks", async ({ page }) => {
test("profile edit networks", async () => {
const profile = randomProfileName();

await startProfileCreation(page, profile);
Expand Down
7 changes: 5 additions & 2 deletions tests/instance-panel.spec.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
import { Page, test } from "@playwright/test";
import { test } from "./basefixtures";
import {
createInstance,
deleteInstance,
randomInstanceName,
} from "./helpers/instances";
// eslint-disable-next-line prettier/prettier
import {
closeInstancePanel,
navigateToInstanceDetails,
openInstancePanel,
startInstanceFromPanel,
stopInstanceFromPanel,
} from "./helpers/instancePanel";
import { Page } from "@playwright/test";

let instance = randomInstanceName();
let page: Page;

test.beforeAll(async ({ browserName, browser }) => {
instance = `${browserName}-${instance}`;
page = await browser.newPage();
await test.startCoverage(page);
await createInstance(page, instance);
});

test.afterAll(async () => {
await deleteInstance(page, instance);
await test.finishCoverage(page);
await page.close();
});

Expand Down
5 changes: 4 additions & 1 deletion tests/instances.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Page, expect, test } from "@playwright/test";
import { expect, test } from "./basefixtures";
import {
createInstance,
deleteInstance,
Expand All @@ -25,6 +25,7 @@ import {
deleteProfile,
randomProfileName,
} from "./helpers/profile";
import { Page } from "@playwright/test";

let instance = randomInstanceName();
let vmInstance = randomInstanceName();
Expand All @@ -35,6 +36,7 @@ test.beforeAll(async ({ browser, browserName }) => {
vmInstance = `${browserName}-${vmInstance}`;
profile = `${browserName}-${profile}`;
page = await browser.newPage();
await test.startCoverage(page);
await createProfile(page, profile);
await createInstance(page, instance);
await createInstance(page, vmInstance, "virtual-machine");
Expand All @@ -44,6 +46,7 @@ test.afterAll(async () => {
await deleteInstance(page, instance);
await deleteInstance(page, vmInstance);
await deleteProfile(page, profile);
await test.finishCoverage(page);
await page.close();
});

Expand Down
Loading

0 comments on commit 92aa46d

Please sign in to comment.