Skip to content

Commit

Permalink
Merge pull request #125 from DataDog/yoann/add-e2e-testing
Browse files Browse the repository at this point in the history
[test] Add e2e testing
  • Loading branch information
yoannmoinet authored Feb 13, 2025
2 parents d30f46f + beeef72 commit d228bf1
Show file tree
Hide file tree
Showing 81 changed files with 1,857 additions and 536 deletions.
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

- 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

0 comments on commit d228bf1

Please sign in to comment.