From 259fabebf1adece900915ed18c5bdbcc6a63b818 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 19 Mar 2026 15:41:59 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20move=20docs=20to=20gen?= =?UTF-8?q?erated-docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{deploy-docs.yml => deploy-generated-docs.yml} | 2 +- .gitignore | 2 +- .prettierignore | 2 +- .wokeignore | 2 +- eslint.config.mjs | 2 +- package.json | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) rename .github/workflows/{deploy-docs.yml => deploy-generated-docs.yml} (97%) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-generated-docs.yml similarity index 97% rename from .github/workflows/deploy-docs.yml rename to .github/workflows/deploy-generated-docs.yml index 9bdcfa0d91..b75099be75 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-generated-docs.yml @@ -50,7 +50,7 @@ jobs: - name: Upload artifact uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 with: - path: './docs' + path: './generated-docs' - name: Deploy to GitHub Pages id: deployment diff --git a/.gitignore b/.gitignore index 3b8d09f074..af4e781f89 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,7 @@ specs.log /test-report/ browserstack.err package.tgz -docs/ +generated-docs/ *.tsbuildinfo /developer-extension/dist /developer-extension/.wxt diff --git a/.prettierignore b/.prettierignore index c83a54ef49..0bb952be52 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,6 +8,6 @@ test/**/dist test/**/.next test/apps/nextjs/next-env.d.ts yarn.lock -/docs +/generated-docs /developer-extension/.output /developer-extension/.wxt diff --git a/.wokeignore b/.wokeignore index 50447e54a0..54364318c0 100644 --- a/.wokeignore +++ b/.wokeignore @@ -1,7 +1,7 @@ **/dist/** yarn.lock .yarn/releases -docs +generated-docs # code import packages/worker/src/domain/deflate.js diff --git a/eslint.config.mjs b/eslint.config.mjs index 9cd92dd0c2..e04724e268 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -37,7 +37,7 @@ export default tseslint.config( 'rum-events-format', '.yarn', '**/playwright-report', - 'docs', + 'generated-docs', 'developer-extension/.wxt', 'developer-extension/dist', ], diff --git a/package.json b/package.json index b8762a3c0f..82da504c7d 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "build": "yarn workspaces foreach --all --parallel --topological run build", "build:bundle": "yarn workspaces foreach --all --parallel run build:bundle", "build:apps": "node scripts/build/build-test-apps.ts", - "build:docs:json": "typedoc --logLevel Verbose --json ./docs.json", - "build:docs:html": "typedoc --out ./docs", + "build:docs:json": "typedoc --logLevel Verbose --json ./generated-docs.json", + "build:docs:html": "typedoc --out ./generated-docs", "pack": "yarn workspaces foreach --all --parallel --include '@datadog/*' exec yarn pack", "format": "prettier --check .", "lint": "NODE_OPTIONS='--max-old-space-size=4096' eslint .", @@ -43,7 +43,7 @@ "json-schemas:generate": "scripts/cli build_json2type && node scripts/generate-schema-types.ts", "size": "node scripts/show-bundle-size.ts", "woke": "scripts/cli woke", - "docs:serve": "typedoc && npx http-server ./docs -p 8080 -o" + "docs:serve": "typedoc && npx http-server ./generated-docs -p 8080 -o" }, "devDependencies": { "@eslint/js": "9.39.3", From 2c1692767cdf2d405072d3915743cae610152998 Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 19 Mar 2026 16:22:37 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=93=9D=20Move=20internal=20docs=20to?= =?UTF-8?q?=20the=20repo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTRIBUTING.md | 47 ++-------- docs/ARCHITECTURE.md | 86 ++++++++++++++++++ docs/CONVENTIONS.md | 201 +++++++++++++++++++++++++++++++++++++++++++ docs/DEVELOPMENT.md | 106 +++++++++++++++++++++++ docs/README.md | 17 ++++ docs/TESTING.md | 68 +++++++++++++++ 6 files changed, 485 insertions(+), 40 deletions(-) create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/CONVENTIONS.md create mode 100644 docs/DEVELOPMENT.md create mode 100644 docs/README.md create mode 100644 docs/TESTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19b8c49ba3..25d2ada089 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,50 +18,17 @@ Have you fixed a bug or written a new feature and want to share it? Many thanks! In order to ease/speed up our review, here are some items you can check/improve when submitting your pull request: +- Follow this repository [Documentation][2] - Keep commits small and focused, rebase your branch if needed. - Write unit and e2e tests for the code you wrote. -- Write meaningful [Commit messages and Pull Request - titles](#commit-messages-and-pull-request-titles) +- Write meaningful [Commit messages and Pull Request titles][3] +- Sign your commits, see [Github's documentation][4] +- Sign the CLA Our CI is not (yet) public, so it may be difficult to understand why your pull request status is failing. Make sure that all tests pass locally, and we'll try to sort it out in our CI. -## Modules usage convention - -Use index.ts files to expose a single, minimal API in directories where modules are used together. -Do not use index.ts when a directory contains independent modules. -An index.ts file should not have exports only used for spec files. - -## Commit messages and Pull Request titles - -Messages should be concise but explanatory. We are using a convention inspired by [gitmoji][2], to -label our Commit messages and Pull Request titles: - -### User-facing changes - -πŸ’₯ - Breaking change. - -✨ - New feature. - -πŸ› - Bug fix. - -⚑️ - Performance improvement. - -πŸ“ - Documentation. - -βš— - Experimental. - -### Internal changes - -πŸ‘· - Updating project setup (continuous integration, build system, package dependencies...). - -♻️ - Refactoring code. - -🎨 - Improving structure / format of the code. - -βœ… - Updating tests. - -πŸ‘Œ - Updating code due to code review changes. - [1]: https://docs.datadoghq.com/help/ -[2]: https://gitmoji.carloscuesta.me/ +[2]: https://github.com/DataDog/browser-sdk/blob/main/docs/README.md +[3]: https://github.com/DataDog/browser-sdk/blob/main/docs/DEVELOPMENT.md#commit-messages-and-pull-request-titles +[4]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000000..f456c993b0 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,86 @@ +# Architecture + +Describes architecture patterns with examples β€” detailed component documentation lives as JSDoc on the files themselves. + +## Package dependencies + +The [monorepo](https://github.com/DataDog/browser-sdk) contains several packages: + +```mermaid +graph TD + core["@datadog/browser-core\n(shared utilities)"] + rum-core["@datadog/browser-rum-core\n(core RUM)"] + rum["@datadog/browser-rum\n(full RUM)"] + rum-slim["@datadog/browser-rum-slim\n(lightweight RUM)"] + rum-react["@datadog/browser-rum-react\n(React integration)"] + logs["@datadog/browser-logs"] + worker["@datadog/browser-worker"] + + core --> rum-core + core --> logs + rum-core --> rum + rum-core --> rum-slim + rum --> rum-react +``` + +## Data processing + +High-level view of RUM SDK data processing. Each box represents a module: + +```mermaid +flowchart TD + startRum["startRum\n(boot)"] + collections["collections\n(views, actions, resources, errors…)"] + assembly["assembly\n(adds common attributes)"] + batch["batch\n(in-memory buffer)"] + + startRum --> collections + collections -->|"raw RUM events"| assembly + assembly -->|"enriched events"| batch +``` + +### startRum [[code](https://github.com/DataDog/browser-sdk/blob/32ffe4bb7e50a37a43794773bbbc57aabb373468/packages/rum-core/src/boot/startRum.ts)] + +Called at SDK initialization. Starts all event data collection. + +### collection [[code](https://github.com/DataDog/browser-sdk/blob/32ffe4bb7e50a37a43794773bbbc57aabb373468/packages/rum-core/src/domain/rumEventsCollection/error/errorCollection.ts)] + +Creates raw RUM events (`views`, `actions`, `resources`, …) by listening to or instrumenting various web APIs, then notifies the assembly. + +### assembly [[code](https://github.com/DataDog/browser-sdk/blob/32ffe4bb7e50a37a43794773bbbc57aabb373468/packages/rum-core/src/domain/assembly.ts)] + +Enriches each event with common attributes (`applicationId`, `service`, `version`, view context, customer context, …) then forwards it to the batch. + +## Data transfer + +```mermaid +flowchart TD + batch["batch\n(in-memory buffer)"] + httpRetry["httpRetry\n(retry & throttle)"] + httpRequest["httpRequest\n(fetch / XHR)"] + intake["Datadog intake"] + + batch -->|"flush"| httpRetry + httpRetry -->|"send"| httpRequest + httpRequest --> intake +``` + +### batch [[code](https://github.com/DataDog/browser-sdk/blob/32ffe4bb7e50a37a43794773bbbc57aabb373468/packages/core/src/transport/batch.ts)] + +Collects events into an in-memory batch. Flushed: + +- Periodically, every `configuration.flushTimeout` (30s by default) +- When the buffer size reaches `configuration.batchBytesLimit` +- When the number of events reaches `configuration.maxBatchSize` +- On `visibilitychange` when the document becomes hidden +- On `beforeunload` + +### httpRetry + +Buffers and retries failed requests (`network failure`, `intake unavailable`, `no connectivity`, …). Also throttles requests when too many are in progress. + +The SDK buffers at most 3MB of requests; older requests are dropped beyond that limit. The buffer is in-memory β€” requests are lost if the tab is closed. + +### httpRequest [[code](https://github.com/DataDog/browser-sdk/blob/32ffe4bb7e50a37a43794773bbbc57aabb373468/packages/core/src/transport/httpRequest.ts)] + +Sends events using `fetch` with `keepAlive`, falling back to `XMLHttpRequest`. diff --git a/docs/CONVENTIONS.md b/docs/CONVENTIONS.md new file mode 100644 index 0000000000..70567f772f --- /dev/null +++ b/docs/CONVENTIONS.md @@ -0,0 +1,201 @@ +# Conventions + +## Dependencies as parameters + +Favor passing a loosely coupled domain dependency as a parameter instead of statically importing it for: + +- **Readability**: Better see which external concepts are involved +- **Testability**: Easily substitute a dependency by a mock to focus on test subject behaviors +- **Extensibility**: Easily replace a dependency with another one with the same signature as needs change + +**Examples:** + +- **OK** to statically import generic utilities + + ```typescript + import { find } from 'utils' + ``` + +- **OK** to split a file for maintenance purpose and statically import the different parts + + ```typescript + import { mySubBehavior } from './mySubBehavior' + import { myOtherSubBehavior } from './myOtherSubBehavior' + + function startMyModule() { + mySubBehavior() + myOtherSubBehavior() + } + ``` + +- For two different modules, with one depending on the other: + - **KO** to statically retrieve the dependency + + ```typescript + import { getOrCreateMyDependency } from './myDependency' + + function startMyModule() { + myDependency = getOrCreateMyDependency() + myDependency.interact() + } + ``` + + - **KO** to statically expose a part of the dependency + + ```typescript + // boot + myDependency = startMyDependency() + myModule = startMyModule() + + // myModule.ts + import { interactWithMyDependency } from './myDependency' + + function startMyModule() { + interactWithMyDependency() + } + ``` + + - **OK** + + ```typescript + // boot + myDependency = startMyDependency() + myOtherDependency = getOrCreateMyDependency() + myModule = startMyModule(myDependency, myOtherDependency) + + // myModule.ts + function startMyModule(myDependency, myOtherDependency) { + myDependency.interact() + myOtherDependency.interact() + } + ``` + +## Avoid global polyfill + +Avoid polluting browser context or conflicting with customer own polyfills. + +**Example:** + +- **KO** to overwrite global API + + ```typescript + window.URL = window.URL || buildUrl(url: string, base?: string) { + ... + } + ``` + +- **OK** to use our own utility internally + + ```typescript + export function buildUrl(url: string, base?: string) { + ... + } + ``` + +## File organization + +In the different packages, we try to split code relative to different concerns to ease discoverability and reusability: + +- **Boot**: code related to API declaration and init phase of the SDK +- **Domain**: code specific to our products: `configuration`, `action`, `views`, `assembly`, ... +- **Tools**: utilities used across the code base without domain logic: `observable`, `timeUtils`, ... +- **Browser**: code wrapping browser APIs without domain logic to use more convenient API, extend capabilities, handle edge cases: `performanceCollection`, `cookie`, ... +- **Transport**: code related to final data transport (server/bridge): `batch`, `httpRequest`, `replicas`, ... + +## Index module usage + +Use index.ts files to expose a single, minimal API in directories where modules are used together. +Do not use index.ts when a directory contains independent modules. +An index.ts file should not have exports only used for spec files. + +**Examples:** + +- Directory with similar but independent modules: `core/src/tools` +- Directory with single domain split in several files: `core/src/transport` + +## Utility files + +It is useful to extract reusable code in "utils" files. + +To increase discoverability and limit the scope of those files, specialize them with a relevant prefix and keep them close to where they are used. + +Examples: `serializationUtils`, `resourceUtils`, ... + +## SpecHelper files + +It is useful to extract tests shared code in "specHelper" files. + +To increase discoverability and limit the scope of those files, specialize them with a relevant prefix and keep them close to where they are used. + +Examples: `htmlAst.specHelper.ts`, `location.specHelper.ts`, ... + +## Size control + +### Favor function over class + +Class syntax does not play well with minification, even without being transpiled as ES5 syntax: + +```javascript +class Batch { + pendingMessages = [] + add(message) { + this.pendingMessages.push(message) + } +} + +// bundled as (64 bytes): +class s { + pendingMessages = [] + add(s) { + this.pendingMessages.push(s) + } +} +``` + +Instead, prefer using closures (or plain functions when possible): + +```javascript +function createBatch() { + const pendingMessages = [] + return { + add(message) { + pendingMessages.push(message) + }, + } +} + +// bundled as (50 bytes): +function n() { + const n = [] + return { + add(t) { + n.push(t) + }, + } +} +``` + +(use `pbpaste | npx terser -m --toplevel` to get the minified version) + +### Favor const enum + +They generally produce less code. + +## Public APIs + +### Don't use enum in public APIs or types + +We want to give the user flexibility on how to specify constant options, to let them choose between hardcoded strings or importing some constant. + +### Use option parameter for customer-provided functions + +```javascript +function customerFn({ foo, bar }) {} // OK +function customerFn(foo, bar) {} // KO +``` + +For functions API (startView, addAction), if we want to support new inputs, we can tweak the behavior to support both old and new inputs and avoid a breaking change. + +However, for customer-provided functions (beforeSend, allowTracingUrl), introducing a change in the input could be a breaking change because the customer implementation would not support it. To have more flexibility in those cases, favor an option input parameter over multiple parameters. + +_Note_: to avoid unnecessary customer migration, don't update existing APIs until it is needed. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000000..75b6c1fe6c --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,106 @@ +# Development + +## Commit messages and Pull Request titles + +Messages should be concise but explanatory. We are using a convention inspired by [gitmoji][1], to +label our Commit messages and Pull Request titles: + +### User-facing changes + +πŸ’₯ - Breaking change. + +✨ - New feature. + +πŸ› - Bug fix. + +⚑️ - Performance improvement. + +πŸ“ - Documentation. + +βš— - Experimental. + +### Internal changes + +πŸ‘· - Updating project setup (continuous integration, build system, package dependencies...). + +♻️ - Refactoring code. + +🎨 - Improving structure / format of the code. + +βœ… - Updating tests. + +πŸ‘Œ - Updating code due to code review changes. + +## Dependency Management + +### Adding Dependencies + +When adding a new dependency, you must update `LICENSE-3rdparty.csv`: + +1. Add entry with format: `Component,Origin,License,Copyright` +2. Use `dev` prefix for all devDependencies (including playground) +3. **Do not include version numbers** - list package name only +4. Maintain alphabetical order by package name +5. Fetch license info from GitHub raw LICENSE file + +**Example:** + +```csv +dev,chokidar,MIT,Copyright (c) 2012 Paul Miller / Elan Shanker +``` + +### License Information Sources + +- Check package repository's LICENSE or package.json +- GitHub: `https://raw.githubusercontent.com/{org}/{repo}/master/LICENSE` +- Extract copyright holder from license file header + +### Updating Dependencies + +Always use latest stable versions for new dependencies. Check with: + +```bash +npm view @latest version +``` + +## RUM Events Schema Management + +Types auto-generated from [rum-events-format](https://github.com/DataDog/rum-events-format) submodule β†’ `src/rumEvent.types.ts` (committed). + +```bash +yarn json-schemas:sync # Update submodule + regenerate types +yarn json-schemas:generate # Regenerate types only +``` + +**Fork dependency**: Uses `bcaudan/json-schema-to-typescript#bcaudan/add-readonly-support` (v11.0.1) for `readonly` modifier support. Built lazily when generating types (not during `yarn install`) to avoid CI rate limiting. + +⚠️ Never edit generated types manually. + +## TypeScript 3.8.2 compatibility + +the CI fails with an error like this: + +``` +Script exited with error: Error: TypeScript 3.8.2 compatibility compatibility broken + ... + node_modules/@datadog/browser-rum-core/cjs/index.d.ts(15,46): error TS1005: ',' expected. +``` + +Reproduce locally with `yarn test:compat:tsc`. + +Check the file mentioned in the error (e.g. `node_modules/@datadog/browser-rum-core/cjs/index.d.ts`). The likely cause is using TypeScript syntax too recent for 3.8.2. For example, combining type and non-type exports on a single line: + +```typescript +// ❌ not supported in TS 3.8.2 +export { createProfilingContextManager, type ProfilingContextManager } from './domain/contexts/profilingContext' +``` + +Split into two separate lines: + +```typescript +// βœ… +export type { ProfilingContextManager } from './domain/contexts/profilingContext' +export { createProfilingContextManager } from './domain/contexts/profilingContext' +``` + +[1]: https://gitmoji.carloscuesta.me/ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..8fae69962d --- /dev/null +++ b/docs/README.md @@ -0,0 +1,17 @@ +# Documentation + +## Policy + +When making changes that impact development workflows or architecture, update the relevant document (see reference below). + +**Keep it concise**: Document the essential information only. Prefer command examples and brief explanations over lengthy descriptions. + +## Reference + +| Document | Purpose | +| ---------------------- | ------------------------------------------------ | +| `docs/DEVELOPMENT.md` | Workflow, dependencies | +| `docs/CONVENTIONS.md` | Coding conventions and style guidelines | +| `docs/ARCHITECTURE.md` | SDK design patterns and event pipeline | +| `docs/TESTING.md` | Unit and E2E testing strategy and infrastructure | +| `scripts/README.md` | Script placement and CLI conventions | diff --git a/docs/TESTING.md b/docs/TESTING.md new file mode 100644 index 0000000000..a9df6d61fb --- /dev/null +++ b/docs/TESTING.md @@ -0,0 +1,68 @@ +# Testing + +## Test my change on my local environment + +1. Run `yarn dev` +2. Open [http://localhost:8080](http://localhost:8080/) in your browser. The [sandbox folder](https://github.com/DataDog/browser-sdk/tree/master/sandbox) is served, with a minimal browser SDK setup. +3. You can use global API via the devtools (see below) or locally modify [index.html](https://github.com/DataDog/browser-sdk/blob/master/sandbox/index.html) to experiment things. + +## Test my change using Claude Code agent + +We have a `/manual-testing` skill ([source](https://github.com/DataDog/browser-sdk/blob/main/.claude/skills/manual-testing/SKILL.md)) to help you test your changes using the dev-server sandbox and [agent-browser](https://agent-browser.dev/). This skill should be able to generate the test instructions for your PR. + +## Test my change on remote environments that use the Browser SDK bundles via CDN + +Use this strategy to test the integration on Real applications. + +1. Install the [developer extension](https://github.com/DataDog/browser-sdk/tree/master/developer-extension) +2. Run `yarn dev` +3. Open the Chrome DevTools browser SDK panel and check "Use dev bundles". + +## Work with unit tests + +1. Write a unit test. +2. Run only your tests by temporarily replacing `describe(...)` with `fdescribe(...)` or `it(...)` with `fit(...)`. +3. Run `yarn test` in the project root. It will launch the tests in watch mode, and also expose [a local URL](http://localhost:9876/) that you can open in any browser. +4. Look at your terminal to see your test results. +5. For deeper investigation, open [the "debug" page](http://localhost:9876/debug.html#) to inspect test execution via the devtools. + +## Debug flaky unit tests + +Top-level `describe` blocks are run in a random order. Sometimes, an issue can only be reproduced with a given order. To reproduce a test run order: + +1. Check the `Randomized with seed XXXX` message from the test output. +2. Temporarily set it as a `seed: XXXX` property in the [jasmine configuration](https://github.com/DataDog/browser-sdk/blob/c876a52fd91e4492d8842c135875fb6c197234b4/test/unit/karma.base.conf.js#L19): + +```js +module.exports = { + // ..., + client: { + jasmine: { + // ..., + seed: 80413, + }, + }, +} +``` + +1. Run `yarn test`. + +## Work with E2E tests + +E2E tests are run via [Playwright](https://playwright.dev/docs/test-configuration). + +**Most useful commands:** + +- `yarn test:e2e --ui` β€” run Playwright locally in [UI mode](https://playwright.dev/docs/test-ui-mode) +- `yarn test:e2e -g "unhandled rejections"` β€” run tests whose names match _"unhandled rejections"_ +- `yarn test:e2e --debug` β€” run Playwright in [debug mode](https://playwright.dev/docs/debug#run-in-debug-mode-1) +- `yarn test:e2e --project firefox` β€” run tests in Firefox. Other options: `chromium` (default), `firefox`, `webkit`, `android`, `*` (all) +- `yarn test:e2e --repeat-each 3` β€” run each test 3 times, useful for catching flaky tests +- `BS_USERNAME= BS_ACCESS_KEY= yarn test:e2e:bs` β€” run the tests in [Browserstack](https://www.browserstack.com/accounts/profile/details) + +> `yarn test:e2e` does not build the SDK automatically. Run `yarn build:bundle` if you have made changes to the SDK source code. + +**Tips:** + +- `expect([1, 2, 3]).toHaveLength(3)` shows a better error message when failing, including the actual array content. +- `await page.pause()` to use with `--debug`. From efef4f82ea121678a49d94607ae2b54b840820fa Mon Sep 17 00:00:00 2001 From: Bastien Caudan Date: Thu, 19 Mar 2026 16:59:24 +0100 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=93=9D=20Combine=20with=20existing=20?= =?UTF-8?q?docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 37 ++++++++++++++----------------------- docs/DEVELOPMENT.md | 36 ++++++++++++++++-------------------- docs/README.md | 15 ++++++++------- docs/TESTING.md | 22 +++++++++------------- 4 files changed, 47 insertions(+), 63 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1fe873727f..fdf86406a0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,6 +60,8 @@ packages/ developer-extension/ # Chrome DevTools extension +docs/ # Repository documentation + test/ β”œβ”€β”€ apps/ # Test apps for E2E and performance testing β”œβ”€β”€ e2e/ # Playwright E2E test scenarios @@ -69,6 +71,17 @@ test/ scripts/ # Build, deploy, release automation ``` +## Documentation + +For deeper context, see: + +- `docs/DEVELOPMENT.md` β€” commit conventions, dependency management, schema generation, TS compatibility +- `docs/CONVENTIONS.md` β€” coding style, file organization, size control +- `docs/ARCHITECTURE.md` β€” package dependencies, data pipeline +- `docs/TESTING.md` β€” local testing strategies, debugging flaky tests +- `scripts/AGENTS.md` β€” writing and organizing scripts in this codebase +- `test/e2e/AGENTS.md` β€” E2E test writing guide (createTest builder, IntakeRegistry, patterns) + ## Critical Patterns ### Unit Tests @@ -102,29 +115,7 @@ scripts/ # Build, deploy, release automation ## Commit Messages -Use gitmoji conventions (based on actual usage in this repo): - -### User-Facing Changes - -- ✨ **New feature** - New public API, behavior, event, property -- πŸ› **Bug fix** - Fix bugs, regressions, crashes -- ⚑️ **Performance** - Improve performance, reduce bundle size -- πŸ’₯ **Breaking change** - Breaking API changes -- πŸ“ **Documentation** - User-facing documentation -- βš—οΈ **Experimental** - New public feature behind a feature flag - -### Internal Changes - -- πŸ‘· **Build/CI** - Dependencies, tooling, deployment, CI config -- ♻️ **Refactor** - Code restructuring, architectural changes -- 🎨 **Code structure** - Improve code structure, formatting -- βœ… **Tests** - Add/fix/improve tests -- πŸ”§ **Configuration** - Config files, project setup -- πŸ”₯ **Removal** - Remove code, features, deprecated items -- πŸ‘Œ **Code review** - Address code review feedback -- 🚨 **Linting** - Add/fix linter rules -- 🧹 **Cleanup** - Minor cleanup, housekeeping -- πŸ”Š **Logging** - Add/modify debug logs, telemetry +Use gitmoji conventions β€” see `docs/DEVELOPMENT.md` for the full reference. ## Git Workflow diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 75b6c1fe6c..5a44409b08 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -7,29 +7,25 @@ label our Commit messages and Pull Request titles: ### User-facing changes -πŸ’₯ - Breaking change. - -✨ - New feature. - -πŸ› - Bug fix. - -⚑️ - Performance improvement. - -πŸ“ - Documentation. - -βš— - Experimental. +- πŸ’₯ **Breaking change** - Breaking API changes +- ✨ **New feature** - New public API, behavior, event, property +- πŸ› **Bug fix** - Fix bugs, regressions, crashes +- ⚑️ **Performance** - Improve performance, reduce bundle size +- πŸ“ **Documentation** - User-facing documentation +- βš—οΈ **Experimental** - New public feature behind a feature flag ### Internal changes -πŸ‘· - Updating project setup (continuous integration, build system, package dependencies...). - -♻️ - Refactoring code. - -🎨 - Improving structure / format of the code. - -βœ… - Updating tests. - -πŸ‘Œ - Updating code due to code review changes. +- πŸ‘· **Build/CI** - Dependencies, tooling, deployment, CI config +- ♻️ **Refactor** - Code restructuring, architectural changes +- 🎨 **Code structure** - Improve code structure, formatting +- βœ… **Tests** - Add/fix/improve tests +- πŸ”§ **Configuration** - Config files, project setup +- πŸ”₯ **Removal** - Remove code, features, deprecated items +- πŸ‘Œ **Code review** - Address code review feedback +- 🚨 **Linting** - Add/fix linter rules +- 🧹 **Cleanup** - Minor cleanup, housekeeping +- πŸ”Š **Logging** - Add/modify debug logs, telemetry ## Dependency Management diff --git a/docs/README.md b/docs/README.md index 8fae69962d..2d7a06e2de 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,10 +8,11 @@ When making changes that impact development workflows or architecture, update th ## Reference -| Document | Purpose | -| ---------------------- | ------------------------------------------------ | -| `docs/DEVELOPMENT.md` | Workflow, dependencies | -| `docs/CONVENTIONS.md` | Coding conventions and style guidelines | -| `docs/ARCHITECTURE.md` | SDK design patterns and event pipeline | -| `docs/TESTING.md` | Unit and E2E testing strategy and infrastructure | -| `scripts/README.md` | Script placement and CLI conventions | +| Document | Purpose | +| ---------------------- | --------------------------------------------------------------- | +| `docs/DEVELOPMENT.md` | Workflow, dependencies | +| `docs/CONVENTIONS.md` | Coding conventions and style guidelines | +| `docs/ARCHITECTURE.md` | SDK design patterns and event pipeline | +| `docs/TESTING.md` | Unit and E2E testing strategy and infrastructure | +| `scripts/AGENTS.md` | Writing and organizing scripts | +| `test/e2e/AGENTS.md` | E2E test writing guide (Playwright, createTest, IntakeRegistry) | diff --git a/docs/TESTING.md b/docs/TESTING.md index a9df6d61fb..fbf523f543 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -49,20 +49,16 @@ module.exports = { ## Work with E2E tests -E2E tests are run via [Playwright](https://playwright.dev/docs/test-configuration). +See `test/e2e/AGENTS.md` for the full E2E testing guide (setup, writing tests, createTest builder, IntakeRegistry, best practices). -**Most useful commands:** +Quick commands: -- `yarn test:e2e --ui` β€” run Playwright locally in [UI mode](https://playwright.dev/docs/test-ui-mode) -- `yarn test:e2e -g "unhandled rejections"` β€” run tests whose names match _"unhandled rejections"_ -- `yarn test:e2e --debug` β€” run Playwright in [debug mode](https://playwright.dev/docs/debug#run-in-debug-mode-1) -- `yarn test:e2e --project firefox` β€” run tests in Firefox. Other options: `chromium` (default), `firefox`, `webkit`, `android`, `*` (all) -- `yarn test:e2e --repeat-each 3` β€” run each test 3 times, useful for catching flaky tests -- `BS_USERNAME= BS_ACCESS_KEY= yarn test:e2e:bs` β€” run the tests in [Browserstack](https://www.browserstack.com/accounts/profile/details) +- `yarn test:e2e:init` β€” first-time setup +- `yarn test:e2e` β€” run all E2E tests +- `yarn test:e2e -g "pattern"` β€” filter by name +- `yarn test:e2e --ui` β€” Playwright UI mode -> `yarn test:e2e` does not build the SDK automatically. Run `yarn build:bundle` if you have made changes to the SDK source code. +## Run tests in browserstack -**Tips:** - -- `expect([1, 2, 3]).toHaveLength(3)` shows a better error message when failing, including the actual array content. -- `await page.pause()` to use with `--debug`. +- `BS_USERNAME= BS_ACCESS_KEY= yarn test:unit:bs` - unit tests +- `BS_USERNAME= BS_ACCESS_KEY= yarn test:e2e:bs` - e2e tests From 0bd9a31337415e81d8dce027e301be80a5b0f57a Mon Sep 17 00:00:00 2001 From: Bastien Caudan <1331991+bcaudan@users.noreply.github.com> Date: Fri, 20 Mar 2026 14:51:55 +0100 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=91=8C=20Simplify=20seed=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Thomas Lebeau <1926949+thomas-lebeau@users.noreply.github.com> --- docs/TESTING.md | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/docs/TESTING.md b/docs/TESTING.md index fbf523f543..28cfce2ad2 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -31,21 +31,7 @@ Use this strategy to test the integration on Real applications. Top-level `describe` blocks are run in a random order. Sometimes, an issue can only be reproduced with a given order. To reproduce a test run order: 1. Check the `Randomized with seed XXXX` message from the test output. -2. Temporarily set it as a `seed: XXXX` property in the [jasmine configuration](https://github.com/DataDog/browser-sdk/blob/c876a52fd91e4492d8842c135875fb6c197234b4/test/unit/karma.base.conf.js#L19): - -```js -module.exports = { - // ..., - client: { - jasmine: { - // ..., - seed: 80413, - }, - }, -} -``` - -1. Run `yarn test`. +2. Run `yarn test:unit --seed XXXX`. ## Work with E2E tests