Initial Portal Runner (#51)
This commit is contained in:
parent
d22cb598a9
commit
3bf42b23dd
|
@ -0,0 +1,6 @@
|
||||||
|
# These options are only needed when if running end to end tests locally
|
||||||
|
PORTAL_RUNNER_USERNAME=
|
||||||
|
PORTAL_RUNNER_PASSWORD=
|
||||||
|
PORTAL_RUNNER_SUBSCRIPTION=
|
||||||
|
PORTAL_RUNNER_RESOURCE_GROUP=
|
||||||
|
PORTAL_RUNNER_DATABASE_ACCOUNT=
|
|
@ -1,6 +1,3 @@
|
||||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
|
||||||
|
|
||||||
name: CI
|
name: CI
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
|
@ -0,0 +1,20 @@
|
||||||
|
name: Runners
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "*/15 * * * *"
|
||||||
|
jobs:
|
||||||
|
sqlcreatecollection:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: "SQL | Create Collection"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v1
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run test:e2e
|
||||||
|
env:
|
||||||
|
PORTAL_RUNNER_APP_INSIGHTS_KEY: ${{ secrets.PORTAL_RUNNER_APP_INSIGHTS_KEY }}
|
||||||
|
PORTAL_RUNNER_USERNAME: ${{ secrets.PORTAL_RUNNER_USERNAME }}
|
||||||
|
PORTAL_RUNNER_PASSWORD: ${{ secrets.PORTAL_RUNNER_PASSWORD }}
|
||||||
|
PORTAL_RUNNER_SUBSCRIPTION: 69e02f2d-f059-4409-9eac-97e8a276ae2c
|
||||||
|
PORTAL_RUNNER_RESOURCE_GROUP: runners
|
||||||
|
PORTAL_RUNNER_DATABASE_ACCOUNT: portal-sql-runner
|
|
@ -16,3 +16,4 @@ notebookapp/*
|
||||||
Contracts/*
|
Contracts/*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.cache/
|
.cache/
|
||||||
|
.env
|
|
@ -70,7 +70,7 @@ Unit tests are located adjacent to the code under test and run with [Jest](https
|
||||||
|
|
||||||
`npm run test`
|
`npm run test`
|
||||||
|
|
||||||
#### End to End Tests
|
#### End to End CI Tests
|
||||||
|
|
||||||
[Cypress](https://www.cypress.io/) is used for end to end tests and are contained in `cypress/`. Currently, it operates as sub project with its own typescript config and dependencies. It also only operates against the emulator. To run cypress tests:
|
[Cypress](https://www.cypress.io/) is used for end to end tests and are contained in `cypress/`. Currently, it operates as sub project with its own typescript config and dependencies. It also only operates against the emulator. To run cypress tests:
|
||||||
|
|
||||||
|
@ -80,6 +80,13 @@ Unit tests are located adjacent to the code under test and run with [Jest](https
|
||||||
4. Install dependencies: `npm install`
|
4. Install dependencies: `npm install`
|
||||||
5. Run cypress headless(`npm run test`) or in interactive mode(`npm run test:debug`)
|
5. Run cypress headless(`npm run test`) or in interactive mode(`npm run test:debug`)
|
||||||
|
|
||||||
|
#### End to End Production Runners
|
||||||
|
|
||||||
|
Jest and Puppeteer are used for end to end production runners and are contained in `test/`. To run these tests locally:
|
||||||
|
|
||||||
|
1. Copy .env.example to .env and fill in all variables
|
||||||
|
2. Run `npm run test:e2e`
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Please read the [contribution guidelines](./CONTRIBUTING.md).
|
Please read the [contribution guidelines](./CONTRIBUTING.md).
|
|
@ -0,0 +1,9 @@
|
||||||
|
const isCI = require("is-ci");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
launch: {
|
||||||
|
headless: isCI,
|
||||||
|
slowMo: isCI ? null : 20,
|
||||||
|
defaultViewport: null
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
preset: "jest-puppeteer",
|
||||||
|
testMatch: ["<rootDir>/test/**/*.spec.[jt]s?(x)"],
|
||||||
|
setupFiles: ["dotenv/config"]
|
||||||
|
};
|
|
@ -150,7 +150,7 @@ module.exports = {
|
||||||
// testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?|ts?)$",
|
// testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?|ts?)$",
|
||||||
|
|
||||||
// This option allows the use of a custom results processor
|
// This option allows the use of a custom results processor
|
||||||
testResultsProcessor: "./trxProcessor.js",
|
// testResultsProcessor: "./trxProcessor.js",
|
||||||
|
|
||||||
// This option allows use of a custom test runner
|
// This option allows use of a custom test runner
|
||||||
// testRunner: "jasmine2",
|
// testRunner: "jasmine2",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
|
@ -37,6 +37,7 @@
|
||||||
"@uifabric/react-cards": "0.109.53",
|
"@uifabric/react-cards": "0.109.53",
|
||||||
"@uifabric/styling": "7.11.2",
|
"@uifabric/styling": "7.11.2",
|
||||||
"abort-controller": "3.0.0",
|
"abort-controller": "3.0.0",
|
||||||
|
"applicationinsights": "1.8.0",
|
||||||
"babel-polyfill": "6.26.0",
|
"babel-polyfill": "6.26.0",
|
||||||
"bootstrap": "3.3.7",
|
"bootstrap": "3.3.7",
|
||||||
"canvas": "2.6.0",
|
"canvas": "2.6.0",
|
||||||
|
@ -48,11 +49,13 @@
|
||||||
"datatables.net-dt": "1.10.19",
|
"datatables.net-dt": "1.10.19",
|
||||||
"date-fns": "1.29.0",
|
"date-fns": "1.29.0",
|
||||||
"dayjs": "1.8.19",
|
"dayjs": "1.8.19",
|
||||||
|
"dotenv": "8.2.0",
|
||||||
"es6-object-assign": "1.1.0",
|
"es6-object-assign": "1.1.0",
|
||||||
"es6-symbol": "3.1.3",
|
"es6-symbol": "3.1.3",
|
||||||
"eslint-plugin-jest": "23.13.2",
|
"eslint-plugin-jest": "23.13.2",
|
||||||
"hasher": "1.2.0",
|
"hasher": "1.2.0",
|
||||||
"immutable": "4.0.0-rc.12",
|
"immutable": "4.0.0-rc.12",
|
||||||
|
"is-ci": "2.0.0",
|
||||||
"jquery": "3.4.0",
|
"jquery": "3.4.0",
|
||||||
"jquery-typeahead": "2.10.6",
|
"jquery-typeahead": "2.10.6",
|
||||||
"jquery-ui-dist": "1.12.1",
|
"jquery-ui-dist": "1.12.1",
|
||||||
|
@ -123,7 +126,7 @@
|
||||||
"enzyme": "3.10.0",
|
"enzyme": "3.10.0",
|
||||||
"enzyme-adapter-react-16": "1.15.1",
|
"enzyme-adapter-react-16": "1.15.1",
|
||||||
"enzyme-to-json": "3.4.3",
|
"enzyme-to-json": "3.4.3",
|
||||||
"eslint": "7.2.0",
|
"eslint": "7.3.1",
|
||||||
"eslint-cli": "1.1.1",
|
"eslint-cli": "1.1.1",
|
||||||
"eslint-plugin-no-null": "1.0.2",
|
"eslint-plugin-no-null": "1.0.2",
|
||||||
"eslint-plugin-react": "7.20.0",
|
"eslint-plugin-react": "7.20.0",
|
||||||
|
@ -134,8 +137,9 @@
|
||||||
"html-loader-jest": "0.2.1",
|
"html-loader-jest": "0.2.1",
|
||||||
"html-webpack-plugin": "3.2.0",
|
"html-webpack-plugin": "3.2.0",
|
||||||
"inline-css": "2.2.5",
|
"inline-css": "2.2.5",
|
||||||
"jest": "24.9.0",
|
"jest": "25.5.4",
|
||||||
"jest-canvas-mock": "2.1.0",
|
"jest-canvas-mock": "2.1.0",
|
||||||
|
"jest-puppeteer": "4.4.0",
|
||||||
"jest-trx-results-processor": "0.0.7",
|
"jest-trx-results-processor": "0.0.7",
|
||||||
"less": "3.8.1",
|
"less": "3.8.1",
|
||||||
"less-loader": "4.1.0",
|
"less-loader": "4.1.0",
|
||||||
|
@ -143,6 +147,7 @@
|
||||||
"mini-css-extract-plugin": "0.4.3",
|
"mini-css-extract-plugin": "0.4.3",
|
||||||
"monaco-editor-webpack-plugin": "1.7.0",
|
"monaco-editor-webpack-plugin": "1.7.0",
|
||||||
"prettier": "1.19.1",
|
"prettier": "1.19.1",
|
||||||
|
"puppeteer": "4.0.0",
|
||||||
"raw-loader": "0.5.1",
|
"raw-loader": "0.5.1",
|
||||||
"rimraf": "3.0.0",
|
"rimraf": "3.0.0",
|
||||||
"sinon": "3.2.1",
|
"sinon": "3.2.1",
|
||||||
|
@ -169,8 +174,8 @@
|
||||||
"pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress",
|
"pack:fast": "node --max_old_space_size=10196 ./node_modules/webpack/bin/webpack.js --mode development --progress",
|
||||||
"copyToConsumers": "node copyToConsumers",
|
"copyToConsumers": "node copyToConsumers",
|
||||||
"test": "rimraf coverage && jest",
|
"test": "rimraf coverage && jest",
|
||||||
|
"test:e2e": "jest -c ./jest.config.e2e.js --detectOpenHandles",
|
||||||
"watch": "npm run start",
|
"watch": "npm run start",
|
||||||
"integrationTest": "runIntegrationTests.cmd",
|
|
||||||
"build:ase": "gulp build:ase",
|
"build:ase": "gulp build:ase",
|
||||||
"compile": "tsc",
|
"compile": "tsc",
|
||||||
"compile:contracts": "tsc -p ./tsconfig.contracts.json",
|
"compile:contracts": "tsc -p ./tsconfig.contracts.json",
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
@echo off
|
|
||||||
|
|
||||||
@for /f "delims=" %%P in ('npm prefix -g') do set "NPM_PREFIX=%%P"
|
|
||||||
@echo npm prefix = %NPM_PREFIX%
|
|
||||||
@echo Compiling TypeScript Test Sources ...
|
|
||||||
call %NPM_PREFIX%\tsc -p ./test
|
|
||||||
if %errorlevel% neq 0 goto end
|
|
||||||
|
|
||||||
copy .\test\Integration\TestRunner.html .\test\out\test\Integration /y >nul 2>&1
|
|
||||||
|
|
||||||
@echo Copying files for test simulation against Emulator ...
|
|
||||||
rmdir "%ProgramFiles%\Azure Cosmos DB Emulator\Packages\DataExplorer\test" >nul 2>&1
|
|
||||||
mkdir "%ProgramFiles%\Azure Cosmos DB Emulator\Packages\DataExplorer\test" >nul 2>&1
|
|
||||||
|
|
||||||
xcopy .\node_modules\jasmine-core\lib .\test\out\lib /s /c /i /r /y >nul 2>&1
|
|
||||||
xcopy .\node_modules\jasmine-core\images .\test\out\lib\images /s /c /i /r /y >nul 2>&1
|
|
||||||
xcopy .\test\out "%ProgramFiles%\Azure Cosmos DB Emulator\Packages\DataExplorer\test" /s /c /i /r /y >nul 2>&1
|
|
||||||
|
|
||||||
@echo Initiating test runner ...
|
|
||||||
start https://localhost:8081/_explorer/test/test/Integration/TestRunner.html
|
|
||||||
@echo Done!
|
|
||||||
|
|
||||||
:end
|
|
||||||
@echo on
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
import "expect-puppeteer";
|
||||||
|
import { trackEvent } from "./utils";
|
||||||
|
|
||||||
|
jest.setTimeout(300000);
|
||||||
|
|
||||||
|
describe("Collection CRUD", () => {
|
||||||
|
it("should complete collection crud", async () => {
|
||||||
|
// Login to Azure Portal
|
||||||
|
await page.goto("https://portal.azure.com");
|
||||||
|
await page.waitFor("input[name=loginfmt]");
|
||||||
|
await page.type("input[name=loginfmt]", process.env.PORTAL_RUNNER_USERNAME);
|
||||||
|
await page.click("input[type=submit]");
|
||||||
|
await page.waitFor(3000);
|
||||||
|
await page.waitFor("input[name=loginfmt]");
|
||||||
|
await page.type("input[name=passwd]", process.env.PORTAL_RUNNER_PASSWORD);
|
||||||
|
await page.click("input[type=submit]");
|
||||||
|
await page.waitFor(3000);
|
||||||
|
await page.waitForNavigation();
|
||||||
|
await page.goto(
|
||||||
|
`https://ms.portal.azure.com/#@microsoft.onmicrosoft.com/resource/subscriptions/${process.env.PORTAL_RUNNER_SUBSCRIPTION}/resourceGroups/${process.env.PORTAL_RUNNER_RESOURCE_GROUP}/providers/Microsoft.DocumentDb/databaseAccounts/${process.env.PORTAL_RUNNER_DATABASE_ACCOUNT}/dataExplorer`
|
||||||
|
);
|
||||||
|
// Wait for page to settle
|
||||||
|
await page.waitFor(10000);
|
||||||
|
// Find Data Explorer iFrame
|
||||||
|
const frames = page.frames();
|
||||||
|
const dataExplorer = frames.find(frame => frame.url().includes("cosmos.azure.com"));
|
||||||
|
// Click "New Container"
|
||||||
|
const newContainerButton = await dataExplorer.$('button[data-test="New Container"]');
|
||||||
|
await newContainerButton.click();
|
||||||
|
// Wait for side pane to appear
|
||||||
|
await dataExplorer.waitFor(".contextual-pane-in");
|
||||||
|
// Fill out New Container form
|
||||||
|
const databaseIdInput = await dataExplorer.$("#databaseId");
|
||||||
|
await databaseIdInput.type("foo");
|
||||||
|
const collectionIdInput = await dataExplorer.$("#containerId");
|
||||||
|
await collectionIdInput.type("foo");
|
||||||
|
const partitionKeyInput = await dataExplorer.$('input[data-test="addCollection-partitionKeyValue"]');
|
||||||
|
await partitionKeyInput.type("/partitionKey");
|
||||||
|
trackEvent({ name: "ProductionRunnerSuccess" });
|
||||||
|
|
||||||
|
// TODO: Submit form and assert results
|
||||||
|
// cy.wrap($body)
|
||||||
|
// .find("#submitBtnAddCollection")
|
||||||
|
// .click();
|
||||||
|
// cy.wait(10000);
|
||||||
|
// cy.wrap($body)
|
||||||
|
// .find('div[data-test="resourceTreeId"]')
|
||||||
|
// .should("exist")
|
||||||
|
// .find('div[class="treeComponent dataResourceTree"]')
|
||||||
|
// .should("contain", dbId);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,15 @@
|
||||||
|
let client;
|
||||||
|
const appInsightsKey = process.env.PORTAL_RUNNER_APP_INSIGHTS_KEY;
|
||||||
|
if (!appInsightsKey) {
|
||||||
|
console.warn(`PORTAL_RUNNER_APP_INSIGHTS_KEY env var not set. Runner telemetry will not be reported`);
|
||||||
|
} else {
|
||||||
|
const appInsights = require("applicationinsights");
|
||||||
|
appInsights.setup(process.env.PORTAL_RUNNER_APP_INSIGHTS_KEY).start();
|
||||||
|
client = appInsights.defaultClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.trackEvent = (...args) => {
|
||||||
|
if (client) {
|
||||||
|
client.trackEvent(...args);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,7 +0,0 @@
|
||||||
var builder = require("jest-trx-results-processor");
|
|
||||||
|
|
||||||
var processor = builder({
|
|
||||||
outputFile: "jest-results.trx"
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = processor;
|
|
Loading…
Reference in New Issue