From bf76590f322b077392b77a8ecb4245d220a67c78 Mon Sep 17 00:00:00 2001 From: uid11 Date: Fri, 2 Sep 2022 05:21:46 +0300 Subject: [PATCH] feat: add dockerImage field to e2ed config; remove E2ED_DOCKER_IMAGE refactor: renamt exit status to exit code --- CONTRIBUTING.md | 2 +- README.md | 18 ++++++++++++++---- bin/addPackageJsonToBuildDocker.sh | 6 ++++++ bin/buildDocker.sh | 6 ++++++ bin/dockerEntrypoint.sh | 4 ++-- bin/getVersion.sh | 2 +- e2ed/bin/runDocker.sh | 12 ++++++------ e2ed/config.ts | 1 + package.json | 5 +++-- src/package/constants/report.ts | 4 ++-- src/package/constants/testRun.ts | 1 + src/package/types/config.ts | 1 + src/package/types/report.ts | 6 +++--- .../utils/events/registerEndE2edRunEvent.ts | 2 +- .../exit/{getExitStatus.ts => getExitCode.ts} | 12 ++++++------ src/package/utils/exit/index.ts | 2 +- src/package/utils/exit/processExit.ts | 10 +++++----- src/package/utils/report/collectReportData.ts | 6 +++--- src/package/utils/report/getLiteReport.ts | 4 ++-- 19 files changed, 65 insertions(+), 39 deletions(-) create mode 100755 bin/addPackageJsonToBuildDocker.sh create mode 100755 bin/buildDocker.sh rename src/package/utils/exit/{getExitStatus.ts => getExitCode.ts} (60%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0940b5a0..7eba9865 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ with the command `npm run lint`. You can check that your changes doesn't break core functionality in runtime by building the project (`npm run build`) and running local tests (`npm run test:local`). -The tests should complete without error, i.e. with an exit status of 0. +The tests should complete without error, i.e. with an exit code 0. If you have [Docker](https://www.docker.com/) installed, you can also run tests in docker (`npm run test:docker`) to make sure they also complete without errors. diff --git a/README.md b/README.md index a612c7bc..6981c1e6 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,11 @@ E2E testing framework over [TestCafe](https://testcafe.io/). +`e2ed` is designed to quickly parallel run a large number of independent atomic tests +(or other scenarios) In an arbitrary browser inside a docker container. +Tests are written in TypeScript, using explicit dependencies and the concept of page objects. +After the run, a detailed html report and a summary in JSON format is generated. + ## Install Requires [node](https://nodejs.org/en/) version 16 or higher: @@ -37,7 +42,15 @@ Then run tests locally for `https://google.com`: E2ED_ORIGIN=https://google.com npx e2ed ``` -And run tests for `https://google.com` in docker: +### Docker + +You can download the latest `e2ed` docker image from https://hub.docker.com/r/e2edhub/e2ed: + +```sh +docker pull e2edhub/e2ed +``` + +And run tests for `https://google.com` in docker container: ```sh E2ED_ORIGIN=https://google.com ./e2ed/bin/runDocker.sh @@ -102,9 +115,6 @@ This parameter can be overridden in the test-specific options. `E2ED_DOCKER_DO_BEFORE_TESTS`: the name of the executable file from the `e2ed/bin` directory that will be run (into container) before running the tests. -`E2ED_DOCKER_IMAGE`: the name of the docker image used to run tests with the `your-project/e2ed/bin/runDocker.sh` command -(`e2ed` by default). - ## License [MIT][license-url] diff --git a/bin/addPackageJsonToBuildDocker.sh b/bin/addPackageJsonToBuildDocker.sh new file mode 100755 index 00000000..d01fe95e --- /dev/null +++ b/bin/addPackageJsonToBuildDocker.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +set -eu + +VERSION=`./bin/getVersion.sh` + +echo "{\n \"dependencies\": {\n \"e2ed\": \"$VERSION\"\n }\n}" > ./build/docker/package.json diff --git a/bin/buildDocker.sh b/bin/buildDocker.sh new file mode 100755 index 00000000..4cf39f53 --- /dev/null +++ b/bin/buildDocker.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh +set -eu + +VERSION=`./bin/getVersion.sh` + +docker build --tag e2edhub/e2ed:$VERSION . diff --git a/bin/dockerEntrypoint.sh b/bin/dockerEntrypoint.sh index f8e021e1..70b12d43 100755 --- a/bin/dockerEntrypoint.sh +++ b/bin/dockerEntrypoint.sh @@ -27,7 +27,7 @@ else node --inspect-brk=0.0.0.0 ./node_modules/e2ed/bin/runE2edInDockerEnvironment.js fi -EXIT_STATUS=$? +EXIT_CODE=$? if [ -z $E2ED_DOCKER_DO_AFTER_TESTS ] then @@ -36,4 +36,4 @@ else ./e2ed/bin/$E2ED_DOCKER_DO_AFTER_TESTS fi -exit $EXIT_STATUS +exit $EXIT_CODE diff --git a/bin/getVersion.sh b/bin/getVersion.sh index e4778b3f..1bcdf448 100755 --- a/bin/getVersion.sh +++ b/bin/getVersion.sh @@ -1,4 +1,4 @@ #!/usr/bin/env sh set -eu -grep -m1 version package.json | cut -d '"' -f 4 +grep -m1 version ./package.json | cut -d '"' -f 4 diff --git a/e2ed/bin/runDocker.sh b/e2ed/bin/runDocker.sh index c4fc7d06..2ba4dc32 100755 --- a/e2ed/bin/runDocker.sh +++ b/e2ed/bin/runDocker.sh @@ -1,16 +1,17 @@ #!/usr/bin/env sh set -e -DIR="${WORKDIR:-$PWD}" -MOUNTDIR="${MOUNTDIR:-$DIR}" -DOCKER_IMAGE="${E2ED_DOCKER_IMAGE:-e2ed}" DEBUG_PORT="${E2ED_DOCKER_DEBUG_PORT:-9229}" +DIR="${E2ED_WORKDIR:-$PWD}" +DOCKER_IMAGE=$(grep -m1 dockerImage ./e2ed/config.ts | sed -e "s/^[^'\"\`]*['\"\`]//" -e "s/['\"\`][^'\"\`]*$//") +MOUNTDIR="${E2ED_MOUNTDIR:-$DIR}" +VERSION=$(grep -m1 \"e2ed\": ./package.json | cut -d '"' -f 4) if [ -z $E2ED_DEBUG ] then PORT="" else - PORT="-p $DEBUG_PORT:$DEBUG_PORT" + PORT="--publish $DEBUG_PORT:$DEBUG_PORT" fi docker run --rm $PORT \ @@ -20,5 +21,4 @@ docker run --rm $PORT \ --env E2ED_DEBUG=$E2ED_DEBUG \ --env E2ED_DOCKER_DO_AFTER_TESTS=$E2ED_DOCKER_DO_AFTER_TESTS \ --env E2ED_DOCKER_DO_BEFORE_TESTS=$E2ED_DOCKER_DO_BEFORE_TESTS \ - --env E2ED_DOCKER_IMAGE=$E2ED_DOCKER_IMAGE \ - $DOCKER_IMAGE + $DOCKER_IMAGE:$VERSION diff --git a/e2ed/config.ts b/e2ed/config.ts index 465fca6c..bcb4c270 100644 --- a/e2ed/config.ts +++ b/e2ed/config.ts @@ -19,6 +19,7 @@ const config: Config = { browserInitTimeout: 30_000, browsers: 'chromium:headless --no-sandbox --disable-dev-shm-usage --disable-web-security', concurrency: isLocalRun ? 1 : 2, + dockerImage: 'e2edhub/e2ed', liteReportFileName: 'lite-report.json', maxRetriesCountInDocker: 3, packTimeout: 90 * 60_000, diff --git a/package.json b/package.json index 2b11a29c..aeda1ecb 100644 --- a/package.json +++ b/package.json @@ -116,10 +116,11 @@ "prerelease": "npm run build", "release": "npm publish ./build/node_modules/e2ed", "postrelease": "if [ -f ./local/postrelease.sh ]; then ./local/postrelease.sh; else echo 'No postrelease hook'; fi", - "build:docker": "docker build -t e2ed .", + "build:docker": "./bin/buildDocker.sh", "pretest:docker": "npm run build:docker && npm run test:docker:copy", "test:docker:copy": "rm -rf ./build/docker && mkdir build/docker && cp -r ./build/e2ed ./build/docker/e2ed", - "test:docker": "(cd ./build/docker && E2ED_DOCKER_DO_AFTER_TESTS=doAfterTests.sh E2ED_DOCKER_DO_BEFORE_TESTS=doBeforeTests.sh E2ED_CONCURRENCY=2 E2ED_DOCKER_RETRIES=3 E2ED_ORIGIN=https://google.com ./e2ed/bin/runDocker.sh)", + "posttest:docker:copy": "./bin/addPackageJsonToBuildDocker.sh", + "test:docker": "(cd ./build/docker && E2ED_DOCKER_DO_AFTER_TESTS=doAfterTests.sh E2ED_DOCKER_DO_BEFORE_TESTS=doBeforeTests.sh E2ED_ORIGIN=https://google.com ./e2ed/bin/runDocker.sh)", "test:esm": "node ./build/testEsmExports.mjs", "test:local": "(cd ./build && E2ED_ORIGIN=https://google.com ./node_modules/e2ed/bin/localEntrypoint.js)", "testcafefork:publish": "./bin/TestCafeFork/publish.sh", diff --git a/src/package/constants/report.ts b/src/package/constants/report.ts index 2a0586b1..915d6a93 100644 --- a/src/package/constants/report.ts +++ b/src/package/constants/report.ts @@ -10,9 +10,9 @@ export const enum EndE2edReason { } /** - * Exit status of e2ed process. + * Exit code of e2ed process. */ -export const enum ExitStatus { +export const enum ExitCode { Passed = 0, Failed = 1, NoRetries = 2, diff --git a/src/package/constants/testRun.ts b/src/package/constants/testRun.ts index 21078a3c..79bb1f76 100644 --- a/src/package/constants/testRun.ts +++ b/src/package/constants/testRun.ts @@ -8,6 +8,7 @@ export const enum TestRunStatus { Failed = 'failed', Skipped = 'skipped', Broken = 'broken', + Manual = 'manual', Unknown = 'unknown', } diff --git a/src/package/types/config.ts b/src/package/types/config.ts index e1497b10..86f250fb 100644 --- a/src/package/types/config.ts +++ b/src/package/types/config.ts @@ -6,6 +6,7 @@ import type {DeepReadonly} from './deep'; * Own e2ed config properties. */ type OwnE2edConfig = Readonly<{ + dockerImage: string; maxRetriesCountInDocker: number; liteReportFileName: string | null; packTimeout: number; diff --git a/src/package/types/report.ts b/src/package/types/report.ts index a187626b..0b96cbb3 100644 --- a/src/package/types/report.ts +++ b/src/package/types/report.ts @@ -1,4 +1,4 @@ -import type {EndE2edReason, ExitStatus, TestRunStatus} from '../constants/internal'; +import type {EndE2edReason, ExitCode, TestRunStatus} from '../constants/internal'; import type {UtcTimeInMs} from './date'; import type {TestFilePath} from './fs'; @@ -13,7 +13,7 @@ export type ReportData = Readonly<{ endE2edReason: EndE2edReason; endTimeInMs: UtcTimeInMs; errors: readonly string[]; - exitStatus: ExitStatus; + exitCode: ExitCode; fullTestRuns: readonly FullTestRun[]; liteReportFileName: string | null; reportFileName: string | null; @@ -28,7 +28,7 @@ export type LiteReport = Readonly<{ endE2edReason: EndE2edReason; endTimeInMs: UtcTimeInMs; errors: readonly string[]; - exitStatus: ExitStatus; + exitCode: ExitCode; liteReportFileName: string; retries: readonly LiteRetry[]; startInfo: StartInfo; diff --git a/src/package/utils/events/registerEndE2edRunEvent.ts b/src/package/utils/events/registerEndE2edRunEvent.ts index 97239995..fe038213 100644 --- a/src/package/utils/events/registerEndE2edRunEvent.ts +++ b/src/package/utils/events/registerEndE2edRunEvent.ts @@ -34,6 +34,6 @@ export const registerEndE2edRunEvent = async (): Promise => { {error}, ); } finally { - processExit(reportData?.exitStatus); + processExit(reportData?.exitCode); } }; diff --git a/src/package/utils/exit/getExitStatus.ts b/src/package/utils/exit/getExitCode.ts similarity index 60% rename from src/package/utils/exit/getExitStatus.ts rename to src/package/utils/exit/getExitCode.ts index 50ac574b..7a70f694 100644 --- a/src/package/utils/exit/getExitStatus.ts +++ b/src/package/utils/exit/getExitCode.ts @@ -1,16 +1,16 @@ -import {ExitStatus, FAILED_TEST_RUN_STATUSES} from '../../constants/internal'; +import {ExitCode, FAILED_TEST_RUN_STATUSES} from '../../constants/internal'; import {assertValueIsDefined} from '../asserts'; import type {Retry} from '../../types/internal'; /** - * Get e2ed exit status (from complete report data). + * Get e2ed exit code (from complete report data). * @internal */ -export const getExitStatus = (retries: readonly Retry[]): ExitStatus => { +export const getExitCode = (retries: readonly Retry[]): ExitCode => { if (retries.length === 0) { - return ExitStatus.NoRetries; + return ExitCode.NoRetries; } const lastRetry = retries[retries.length - 1]; @@ -21,8 +21,8 @@ export const getExitStatus = (retries: readonly Retry[]): ExitStatus => { const hasFailedTests = fullTestRuns.some(({status}) => FAILED_TEST_RUN_STATUSES.includes(status)); if (hasFailedTests) { - return ExitStatus.Failed; + return ExitCode.Failed; } - return ExitStatus.Passed; + return ExitCode.Passed; }; diff --git a/src/package/utils/exit/index.ts b/src/package/utils/exit/index.ts index 4c4b9490..d13f2e4a 100644 --- a/src/package/utils/exit/index.ts +++ b/src/package/utils/exit/index.ts @@ -1,2 +1,2 @@ -export * from './getExitStatus'; +export * from './getExitCode'; export * from './processExit'; diff --git a/src/package/utils/exit/processExit.ts b/src/package/utils/exit/processExit.ts index 316c866c..d61c8b9c 100644 --- a/src/package/utils/exit/processExit.ts +++ b/src/package/utils/exit/processExit.ts @@ -1,13 +1,13 @@ -import {ExitStatus} from '../../constants/internal'; +import {ExitCode} from '../../constants/internal'; import {generalLog} from '../generalLog'; /** - * Exit from e2ed process with correct exit status. + * Exit from e2ed process with correct exit code. * @internal */ -export const processExit = (exitStatus: ExitStatus = ExitStatus.NoReportData): void => { - generalLog(`Exit from e2ed with status ${exitStatus}`); +export const processExit = (exitCode: ExitCode = ExitCode.NoReportData): void => { + generalLog(`Exit from e2ed with code ${exitCode}`); - process.exit(exitStatus); + process.exit(exitCode); }; diff --git a/src/package/utils/report/collectReportData.ts b/src/package/utils/report/collectReportData.ts index 9fbcd139..e81f26d9 100644 --- a/src/package/utils/report/collectReportData.ts +++ b/src/package/utils/report/collectReportData.ts @@ -1,4 +1,4 @@ -import {getExitStatus} from '../exit'; +import {getExitCode} from '../exit'; import {getFullConfig} from '../getFullConfig'; import {assertThatTestNamesAndFilePathsAreUnique} from './assertThatTestNamesAndFilePathsAreUnique'; @@ -27,13 +27,13 @@ export const collectReportData = async ({ unificateRunHashes(fullTestRuns); const retries = getRetries(fullTestRuns); - const exitStatus = getExitStatus(retries); + const exitCode = getExitCode(retries); return { endE2edReason, endTimeInMs, errors, - exitStatus, + exitCode, fullTestRuns, liteReportFileName, reportFileName, diff --git a/src/package/utils/report/getLiteReport.ts b/src/package/utils/report/getLiteReport.ts index fed8c97a..92811c50 100644 --- a/src/package/utils/report/getLiteReport.ts +++ b/src/package/utils/report/getLiteReport.ts @@ -9,7 +9,7 @@ import type {LiteReport, ReportData} from '../../types/internal'; * @internal */ export const getLiteReport = (reportData: ReportData): LiteReport => { - const {endE2edReason, endTimeInMs, errors, exitStatus, liteReportFileName, retries, startInfo} = + const {endE2edReason, endTimeInMs, errors, exitCode, liteReportFileName, retries, startInfo} = reportData; assertValueIsNotNull(liteReportFileName, 'liteReportFileName is not null'); @@ -20,7 +20,7 @@ export const getLiteReport = (reportData: ReportData): LiteReport => { endE2edReason, endTimeInMs, errors, - exitStatus, + exitCode, liteReportFileName, retries: liteRetries, startInfo,