Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[test] Add e2e testing #125

Merged
merged 14 commits into from
Feb 13, 2025
Merged
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
109 changes: 105 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,126 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Install Node ${{matrix.node.node-version || matrix.node.node-version-file}}
uses: actions/setup-node@v4
with: ${{matrix.node}}

- name: Cache build:all
id: cache-build
uses: actions/cache@v4
with:
path: packages/published/**/dist
key: ${{ matrix.node }}-cache-build-${{ hashFiles('packages/published/**', 'yarn.lock') }}

- run: yarn install
- run: yarn build:all
- run: yarn test

- name: Build all plugins
if: steps.cache-build.outputs.cache-hit != 'true'
run: yarn build:all

- run: yarn test:unit

e2e:
strategy:
fail-fast: false
matrix:
node:
- 18

timeout-minutes: 10

name: End to End
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Node ${{matrix.node}}.x
uses: actions/setup-node@v4
with:
node-version: ${{matrix.node}}.x

- name: Cache build:all
id: cache-build
uses: actions/cache@v4
with:
path: packages/published/**/dist
key: ${{ matrix.node }}-cache-build-${{ hashFiles('packages/published/**', 'yarn.lock') }}

- name: Cache playwright binaries
id: cache-playwright-binaries
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
%USERPROFILE%\AppData\Local\ms-playwright
key: cache-playwright-binaries-${{ hashFiles('yarn.lock') }}

- run: yarn install

- name: Install playwright
run: yarn workspace @dd/tests playwright install --with-deps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that this step will still run even when the playwright cache is hit

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is necessary, we can only cache the binaries, but we still need to install some shared libraries (installed in a different directory than the binaries).

Though, it will not need to download the binaries (browsers mostly).


- name: Build all plugins
if: steps.cache-build.outputs.cache-hit != 'true'
run: yarn build:all

- run: yarn test:e2e

- name: Save playwright cache
if: always() && steps.cache-playwright-binaries.outputs.cache-hit != 'true'
id: save-playwright-cache
uses: actions/cache/save@v4
with:
path: |
~/.cache/ms-playwright
~/Library/Caches/ms-playwright
%USERPROFILE%\AppData\Local\ms-playwright
key: cache-playwright-binaries-${{ hashFiles('yarn.lock') }}

- uses: actions/upload-artifact@v4
if: ${{ !cancelled() && failure() }}
with:
name: playwright
path: |
packages/tests/playwright-report
packages/tests/test-results
retention-days: 3

lint:
strategy:
matrix:
node:
- 18

name: Linting
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Install node

- name: Install Node ${{matrix.node}}.x
uses: actions/setup-node@v4
with:
node-version-file: 'package.json'

- name: Cache build:all
id: cache-build
uses: actions/cache@v4
with:
path: packages/published/**/dist
key: ${{ matrix.node }}-cache-build-${{ hashFiles('packages/published/**', 'yarn.lock') }}

- run: yarn install
- run: yarn build:all

- name: Build all plugins
if: steps.cache-build.outputs.cache-hit != 'true'
run: yarn build:all

- run: yarn typecheck:all

- run: yarn cli integrity

- run: git diff --exit-code && git diff --cached --exit-code || (echo "Please run 'yarn cli integrity' and commit the result." && exit 1)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-19706e7e35-10.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions LICENSES-3rdparty.csv
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,10 @@ Component,Origin,Licence,Copyright
@nodelib/fs.walk,npm,MIT,(https://www.npmjs.com/package/@nodelib/fs.walk)
@pkgjs/parseargs,npm,MIT,(https://github.com/pkgjs/parseargs#readme)
@pkgr/core,npm,MIT,JounQin (https://github.com/un-ts/pkgr/blob/master/packages/core)
@playwright/test,npm,Apache-2.0,Microsoft Corporation (https://playwright.dev)
@rollup/plugin-babel,virtual,MIT,Rich Harris (https://github.com/rollup/plugins/tree/master/packages/babel#readme)
@rollup/plugin-commonjs,virtual,MIT,Rich Harris (https://github.com/rollup/plugins/tree/master/packages/commonjs/#readme)
@rollup/plugin-esm-shim,virtual,MIT,Peter Placzek (https://github.com/rollup/plugins/tree/master/packages/esm-shim#readme)
@rollup/plugin-json,virtual,MIT,rollup (https://github.com/rollup/plugins/tree/master/packages/json#readme)
@rollup/plugin-node-resolve,virtual,MIT,Rich Harris (https://github.com/rollup/plugins/tree/master/packages/node-resolve/#readme)
@rollup/plugin-terser,virtual,MIT,Peter Placzek (https://github.com/rollup/plugins/tree/master/packages/terser#readme)
Expand Down Expand Up @@ -206,6 +208,8 @@ Component,Origin,Licence,Copyright
@types/jest,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/jest)
@types/json-schema,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/json-schema)
@types/json5,npm,MIT,Jason Swearingen (https://www.npmjs.com/package/@types/json5)
@types/lodash,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash)
@types/lodash.template,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/lodash.template)
@types/minimatch,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/minimatch)
@types/mute-stream,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mute-stream)
@types/node,npm,MIT,(https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node)
Expand Down Expand Up @@ -641,9 +645,12 @@ listr2,npm,MIT,Cenk Kilic (https://srcs.kilic.dev)
loader-runner,npm,MIT,Tobias Koppers @sokra (https://github.com/webpack/loader-runner#readme)
loader-utils,npm,MIT,Tobias Koppers @sokra (https://www.npmjs.com/package/loader-utils)
locate-path,npm,MIT,Sindre Sorhus (sindresorhus.com)
lodash._reinterpolate,npm,MIT,John-David Dalton (https://lodash.com/)
lodash.debounce,npm,MIT,John-David Dalton (https://lodash.com/)
lodash.memoize,npm,MIT,John-David Dalton (https://lodash.com/)
lodash.merge,npm,MIT,John-David Dalton (https://lodash.com/)
lodash.template,npm,MIT,John-David Dalton (https://lodash.com/)
lodash.templatesettings,npm,MIT,John-David Dalton (https://lodash.com/)
log-symbols,npm,MIT,Sindre Sorhus (sindresorhus.com)
log-update,npm,MIT,Sindre Sorhus (sindresorhus.com)
lru-cache,npm,ISC,Isaac Z. Schlueter (https://www.npmjs.com/package/lru-cache)
Expand Down Expand Up @@ -740,6 +747,8 @@ picomatch,npm,MIT,Jon Schlinkert (https://github.com/micromatch/picomatch)
pify,npm,MIT,Sindre Sorhus (sindresorhus.com)
pirates,npm,MIT,Ari Porad (https://github.com/danez/pirates#readme)
pkg-dir,npm,MIT,Sindre Sorhus (sindresorhus.com)
playwright,npm,Apache-2.0,Microsoft Corporation (https://playwright.dev)
playwright-core,npm,Apache-2.0,Microsoft Corporation (https://playwright.dev)
please-upgrade-node,npm,MIT,typicode (https://github.com/typicode/please-upgrade-node#readme)
posix-character-classes,npm,MIT,Jon Schlinkert (https://github.com/jonschlinkert/posix-character-classes)
possible-typed-array-names,npm,MIT,Jordan Harband (https://github.com/ljharb/possible-typed-array-names#readme)
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"loop": "yarn workspaces foreach -Apti --include \"@datadog/*\" --exclude \"@datadog/build-plugins\"",
"oss": "yarn cli oss -d packages -l mit",
"publish:all": "yarn loop --no-private npm publish",
"test": "yarn workspace @dd/tests test",
"typecheck:all": "yarn workspaces foreach -Apti run typecheck",
"version:all": "yarn loop version --deferred ${0} && yarn version apply --all",
"watch:all": "yarn loop run watch"
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export const FULL_NAME_BUNDLERS = [
'webpack4',
'webpack5',
] as const;
export const ENV_VAR_REQUESTED_BUNDLERS = 'PLAYWRIGHT_REQUESTED_BUNDLERS';
168 changes: 167 additions & 1 deletion packages/core/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@ import { glob } from 'glob';
import path from 'path';
import type { RequestInit } from 'undici-types';

import type { GlobalContext, Logger, RequestOpts, ResolvedEntry } from './types';
import type {
BuildReport,
Entry,
File,
GlobalContext,
Input,
Logger,
Output,
RequestOpts,
ResolvedEntry,
SerializedBuildReport,
SerializedEntry,
SerializedInput,
SerializedOutput,
} from './types';

// Format a duration 0h 0m 0s 0ms
export const formatDuration = (duration: number) => {
Expand Down Expand Up @@ -244,3 +258,155 @@ export const readJsonSync = (filepath: string) => {

let index = 0;
export const getUniqueId = () => `${Date.now()}.${performance.now()}.${++index}`;

// Returns an object that is safe to serialize to JSON.
// Mostly useful for debugging and testing.
export const serializeBuildReport = (report: BuildReport): SerializedBuildReport => {
// Report is an object that self reference some of its values.
// To make it JSON serializable, we need to remove the self references
// and replace them with strings, we'll use "filepath" to still have them uniquely identifiable.
const jsonReport: SerializedBuildReport = {
bundler: report.bundler,
errors: report.errors,
warnings: report.warnings,
logs: report.logs,
start: report.start,
end: report.end,
duration: report.duration,
writeDuration: report.writeDuration,
entries: [],
inputs: [],
outputs: [],
};

for (const entry of report.entries || []) {
const newEntry: SerializedEntry = { ...entry, inputs: [], outputs: [] };
if (entry.inputs) {
newEntry.inputs = entry.inputs.map((file: File) => file.filepath);
}
if (entry.outputs) {
newEntry.outputs = entry.outputs.map((file: File) => file.filepath);
}
jsonReport.entries.push(newEntry);
}

for (const input of report.inputs || []) {
const newInput: SerializedInput = { ...input, dependencies: [], dependents: [] };
if (input.dependencies) {
for (const dependency of input.dependencies) {
newInput.dependencies.push(dependency.filepath);
}
}
if (input.dependents) {
for (const dependent of input.dependents) {
newInput.dependents.push(dependent.filepath);
}
}
jsonReport.inputs.push(newInput);
}

for (const output of report.outputs || []) {
const newOutput: SerializedOutput = { ...output, inputs: [] };
if (output.inputs) {
newOutput.inputs = output.inputs.map((file: File) => file.filepath);
}
jsonReport.outputs.push(newOutput);
}

return jsonReport;
};

// Returns an object that is unserialized from serializeBuildReport().
// Mostly useful for debugging and testing.
export const unserializeBuildReport = (report: SerializedBuildReport): BuildReport => {
const buildReport: BuildReport = {
bundler: report.bundler,
errors: report.errors,
warnings: report.warnings,
logs: report.logs,
start: report.start,
end: report.end,
duration: report.duration,
writeDuration: report.writeDuration,
};

const reportInputs = report.inputs || [];
const reportOutputs = report.outputs || [];

const entries: Entry[] = [];

// Prefill inputs and outputs as they are sometimes self-referencing themselves.
const indexedInputs: Map<string, Input> = new Map();
const inputs: Input[] = reportInputs.map<Input>((input) => {
const newInput: Input = {
...input,
// Keep them empty for now, we'll fill them later.
dependencies: new Set(),
dependents: new Set(),
};
indexedInputs.set(input.filepath, newInput);
return newInput;
});

const indexedOutputs: Map<string, Output> = new Map();
const outputs: Output[] = reportOutputs.map<Output>((output) => {
const newOutput: Output = { ...output, inputs: [] };
indexedOutputs.set(output.filepath, newOutput);
return newOutput;
});

// Fill in the inputs' dependencies and dependents.
for (const input of reportInputs) {
const newInput: Input = indexedInputs.get(input.filepath)!;

// Re-assign the dependencies and dependents to the actual objects.
if (input.dependencies) {
for (const dependency of input.dependencies) {
const newDependency = indexedInputs.get(dependency)!;
newInput.dependencies.add(newDependency);
}
}
if (input.dependents) {
for (const dependent of input.dependents) {
const newDependent = indexedInputs.get(dependent)!;
newInput.dependents.add(newDependent);
}
}
}

// Fill in the outputs' inputs.
for (const output of reportOutputs) {
const newOutput: Output = indexedOutputs.get(output.filepath)!;
if (output.inputs) {
// Re-assign the inputs to the actual objects.
newOutput.inputs = output.inputs
.map<
// Can be either an input or an output (for sourcemaps).
Input | Output | undefined
>((filepath: string) => indexedInputs.get(filepath) || indexedOutputs.get(filepath))
.filter(Boolean) as (Input | Output)[];
}
}

for (const entry of report.entries || []) {
const newEntry: Entry = { ...entry, inputs: [], outputs: [] };
if (entry.inputs) {
newEntry.inputs = entry.inputs
.map((filepath: string) => indexedInputs.get(filepath))
.filter(Boolean) as (Output | Input)[];
}
if (entry.outputs) {
newEntry.outputs = entry.outputs
.map((filepath: string) => indexedOutputs.get(filepath))
.filter(Boolean) as Output[];
}
entries.push(newEntry);
}

return {
...buildReport,
entries,
inputs,
outputs,
};
};
Loading