mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-06-11 23:17:38 +01:00
Code coverage pre-QA push.
This commit is contained in:
@@ -161,6 +161,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
NODE_TLS_REJECT_UNAUTHORIZED: 0
|
NODE_TLS_REJECT_UNAUTHORIZED: 0
|
||||||
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
|
||||||
|
COVERAGE: "true"
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -219,6 +220,13 @@ jobs:
|
|||||||
name: blob-report-${{ matrix.shardIndex }}
|
name: blob-report-${{ matrix.shardIndex }}
|
||||||
path: blob-report
|
path: blob-report
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
- name: Upload coverage data
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverage-data-${{ matrix.shardIndex }}
|
||||||
|
path: .nyc_output
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
merge-playwright-reports:
|
merge-playwright-reports:
|
||||||
name: "Merge Playwright Reports"
|
name: "Merge Playwright Reports"
|
||||||
@@ -251,3 +259,39 @@ jobs:
|
|||||||
name: html-report--attempt-${{ github.run_attempt }}
|
name: html-report--attempt-${{ github.run_attempt }}
|
||||||
path: playwright-report
|
path: playwright-report
|
||||||
retention-days: 14
|
retention-days: 14
|
||||||
|
|
||||||
|
merge-coverage:
|
||||||
|
name: "Merge Code Coverage"
|
||||||
|
if: ${{ !cancelled() }}
|
||||||
|
needs: [playwright-tests]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Download coverage data from all shards
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: all-coverage
|
||||||
|
pattern: coverage-data-*
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Merge coverage data
|
||||||
|
run: |
|
||||||
|
mkdir -p .nyc_output
|
||||||
|
cp all-coverage/*.json .nyc_output/ 2>/dev/null || true
|
||||||
|
npx nyc merge .nyc_output .nyc_output/merged-coverage.json
|
||||||
|
|
||||||
|
- name: Generate coverage report
|
||||||
|
run: npx nyc report --temp-dir .nyc_output --report-dir coverage-e2e --reporter text --reporter text-summary --reporter lcov --reporter html
|
||||||
|
|
||||||
|
- name: Upload coverage report
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: coverage-report--attempt-${{ github.run_attempt }}
|
||||||
|
path: coverage-e2e
|
||||||
|
retention-days: 14
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
built/*
|
built/*
|
||||||
dist/*
|
dist/*
|
||||||
coverage/**
|
coverage/**
|
||||||
|
coverage-e2e/**
|
||||||
|
.nyc_output/
|
||||||
css/*
|
css/*
|
||||||
Definitions/**/*
|
Definitions/**/*
|
||||||
libs/**/*
|
libs/**/*
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": "@istanbuljs/nyc-config-typescript",
|
||||||
|
"all": true,
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
||||||
|
"exclude": [
|
||||||
|
"src/**/*.test.ts",
|
||||||
|
"src/**/*.test.tsx",
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.spec.tsx",
|
||||||
|
"src/**/*.d.ts",
|
||||||
|
"src/setupTests.ts"
|
||||||
|
],
|
||||||
|
"reporter": ["text", "text-summary", "lcov", "html"],
|
||||||
|
"report-dir": "coverage-e2e",
|
||||||
|
"temp-dir": ".nyc_output"
|
||||||
|
}
|
||||||
Generated
+1075
-192
File diff suppressed because it is too large
Load Diff
@@ -152,6 +152,7 @@
|
|||||||
"@webpack-cli/serve": "2.0.5",
|
"@webpack-cli/serve": "2.0.5",
|
||||||
"babel-jest": "29.7.0",
|
"babel-jest": "29.7.0",
|
||||||
"babel-loader": "8.1.0",
|
"babel-loader": "8.1.0",
|
||||||
|
"babel-plugin-istanbul": "7.0.1",
|
||||||
"buffer": "5.1.0",
|
"buffer": "5.1.0",
|
||||||
"case-sensitive-paths-webpack-plugin": "2.4.0",
|
"case-sensitive-paths-webpack-plugin": "2.4.0",
|
||||||
"create-file-webpack": "1.0.2",
|
"create-file-webpack": "1.0.2",
|
||||||
@@ -182,6 +183,7 @@
|
|||||||
"mini-css-extract-plugin": "2.1.0",
|
"mini-css-extract-plugin": "2.1.0",
|
||||||
"monaco-editor-webpack-plugin": "7.1.0",
|
"monaco-editor-webpack-plugin": "7.1.0",
|
||||||
"node-fetch": "2.6.7",
|
"node-fetch": "2.6.7",
|
||||||
|
"nyc": "18.0.0",
|
||||||
"prettier": "3.0.3",
|
"prettier": "3.0.3",
|
||||||
"process": "0.11.10",
|
"process": "0.11.10",
|
||||||
"querystring-es3": "0.2.1",
|
"querystring-es3": "0.2.1",
|
||||||
@@ -213,6 +215,9 @@
|
|||||||
"test": "rimraf coverage && jest",
|
"test": "rimraf coverage && jest",
|
||||||
"test:debug": "jest --runInBand",
|
"test:debug": "jest --runInBand",
|
||||||
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles",
|
"test:e2e": "jest -c ./jest.config.playwright.js --detectOpenHandles",
|
||||||
|
"test:e2e:coverage": "COVERAGE=true npx playwright test",
|
||||||
|
"coverage:merge": "nyc merge .nyc_output .nyc_output/merged-coverage.json",
|
||||||
|
"coverage:report": "nyc report --temp-dir .nyc_output --report-dir coverage-e2e --reporter text --reporter text-summary --reporter lcov --reporter html",
|
||||||
"test:file": "jest --coverage=false",
|
"test:file": "jest --coverage=false",
|
||||||
"watch": "npm run start",
|
"watch": "npm run start",
|
||||||
"wait-for-server": "wait-on -t 240000 -i 5000 -v https-get://0.0.0.0:1234/",
|
"wait-for-server": "wait-on -t 240000 -i 5000 -v https-get://0.0.0.0:1234/",
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { test as base, expect, Page, TestInfo } from "@playwright/test";
|
||||||
|
import * as crypto from "crypto";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import * as path from "path";
|
||||||
|
|
||||||
|
const NYC_OUTPUT_DIR = path.resolve(__dirname, "../.nyc_output");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extended Playwright test that automatically collects Istanbul code coverage
|
||||||
|
* from all frames after each test. Coverage is only collected when the
|
||||||
|
* COVERAGE environment variable is set to "true".
|
||||||
|
*
|
||||||
|
* Istanbul instrumentation must be enabled in the webpack build (see webpack.config.js).
|
||||||
|
* The instrumented code exposes `window.__coverage__` which this fixture collects.
|
||||||
|
*/
|
||||||
|
export const test = base.extend<{ coverageAutoCollect: void }>({
|
||||||
|
coverageAutoCollect: [
|
||||||
|
async ({ page }: { page: Page }, use: () => Promise<void>, testInfo: TestInfo) => {
|
||||||
|
// Run the test
|
||||||
|
await use();
|
||||||
|
|
||||||
|
// After the test, collect coverage if enabled
|
||||||
|
if (process.env.COVERAGE !== "true") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the output directory exists
|
||||||
|
if (!fs.existsSync(NYC_OUTPUT_DIR)) {
|
||||||
|
fs.mkdirSync(NYC_OUTPUT_DIR, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect coverage from all frames (the app runs inside an iframe)
|
||||||
|
for (const frame of page.frames()) {
|
||||||
|
try {
|
||||||
|
const coverage = await frame.evaluate(() => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
return (window as any).__coverage__ || null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (coverage) {
|
||||||
|
const uniqueId = crypto.randomBytes(8).toString("hex");
|
||||||
|
const safeName = testInfo.title.replace(/[^a-zA-Z0-9]/g, "_").substring(0, 60);
|
||||||
|
const filename = `coverage-${safeName}-${uniqueId}.json`;
|
||||||
|
fs.writeFileSync(path.join(NYC_OUTPUT_DIR, filename), JSON.stringify(coverage));
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Frame may have been detached or navigated away. That's fine, skip it.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ auto: true },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export { expect };
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { setupCORSBypass } from "../CORSBypass";
|
import { setupCORSBypass } from "../CORSBypass";
|
||||||
import { DataExplorer, DocumentsTab, TestAccount } from "../fx";
|
import { DataExplorer, DocumentsTab, TestAccount } from "../fx";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, DocumentsTab, TestAccount } from "../fx";
|
import { DataExplorer, DocumentsTab, TestAccount } from "../fx";
|
||||||
import { retry, setPartitionKeys } from "../testData";
|
import { retry, setPartitionKeys } from "../testData";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, Editor, QueryTab, TestAccount } from "../fx";
|
import { DataExplorer, Editor, QueryTab, TestAccount } from "../fx";
|
||||||
import { TestContainerContext, TestItem, createTestSQLContainer } from "../testData";
|
import { TestContainerContext, TestItem, createTestSQLContainer } from "../testData";
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { CosmosDBManagementClient } from "@azure/arm-cosmosdb";
|
import { CosmosDBManagementClient } from "@azure/arm-cosmosdb";
|
||||||
import { CosmosClient, PermissionMode } from "@azure/cosmos";
|
import { CosmosClient, PermissionMode } from "@azure/cosmos";
|
||||||
import { AzureIdentityCredentialAdapter } from "@azure/ms-rest-js";
|
import { AzureIdentityCredentialAdapter } from "@azure/ms-rest-js";
|
||||||
import {
|
import {
|
||||||
DataExplorer,
|
DataExplorer,
|
||||||
TestAccount,
|
TestAccount,
|
||||||
generateUniqueName,
|
generateUniqueName,
|
||||||
getAccountName,
|
getAccountName,
|
||||||
getAzureCLICredentials,
|
getAzureCLICredentials,
|
||||||
resourceGroupName,
|
resourceGroupName,
|
||||||
subscriptionId,
|
subscriptionId,
|
||||||
} from "../fx";
|
} from "../fx";
|
||||||
|
|
||||||
test("SQL account using Resource token", async ({ page }) => {
|
test("SQL account using Resource token", async ({ page }) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
import { DataExplorer, TestAccount } from "../fx";
|
import { DataExplorer, TestAccount } from "../fx";
|
||||||
|
|
||||||
test("Self Serve", async ({ page, browserName }) => {
|
test("Self Serve", async ({ page, browserName }) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { expect, test } from "@playwright/test";
|
import { expect, test } from "../baseTest";
|
||||||
|
|
||||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||||
|
|
||||||
|
|||||||
+20
-8
@@ -65,16 +65,28 @@ const htmlRule = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// We compile our own code with ts-loader
|
// We compile our own code with ts-loader
|
||||||
|
const typescriptLoaders = [
|
||||||
|
{
|
||||||
|
loader: "ts-loader",
|
||||||
|
options: {
|
||||||
|
transpileOnly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// When COVERAGE is enabled, add babel-loader with istanbul plugin to instrument code
|
||||||
|
if (process.env.COVERAGE === "true") {
|
||||||
|
typescriptLoaders.unshift({
|
||||||
|
loader: "babel-loader",
|
||||||
|
options: {
|
||||||
|
plugins: ["istanbul"],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const typescriptRule = {
|
const typescriptRule = {
|
||||||
test: /\.tsx?$/,
|
test: /\.tsx?$/,
|
||||||
use: [
|
use: typescriptLoaders,
|
||||||
{
|
|
||||||
loader: "ts-loader",
|
|
||||||
options: {
|
|
||||||
transpileOnly: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user