Skip to content

Commit 0623f9b

Browse files
committed
Update CI "Upload strategies" page to mention new advanced upload options
1 parent b5eb76f commit 0623f9b

File tree

1 file changed

+156
-108
lines changed
  • src/app/reference/ci-workflows/upload-strategies

1 file changed

+156
-108
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,27 @@
11
---
22
title: Upload strategies
3-
description: When you run tests and create recordings, they are stored locally. You can opt to upload them automatically or define your own uploading strategy. All uploaded recordings become accessible in the Replay App.
3+
description: When you run tests and create recordings, they are stored locally. You can choose which recordings get uploaded to Replay. All uploaded recordings become accessible in the Replay App.
44
---
55

66
{% callout %}
7-
While uploading just failed test is good for saving resources, our recommendation is to upload both failed and passed tests so that you can compare them. This can be really useful for debugging purposes.
7+
While uploading just failed tests is good for saving resources, our recommendation is to upload both failed and passed tests so that you can compare them. This can be really useful for debugging purposes.
88
{% /callout %}
99

10-
## Upload failed tests only
10+
## Upload all tests
1111

12-
By default, all test replays are uploaded no matter the result. If you want to upload only the failed recordings, you can use the `filter` property in the plugin configuration:
12+
To upload all test replays no matter the result, set the `upload` option to true.
1313

1414
{% tabs labels=["cypress", "playwright"] %}
1515
{% tab %}
1616

17-
```js
17+
```js {% fileName="cypress.config.js" highlight=[7] %}
1818
export default defineConfig({
1919
e2e: {
2020
setupNodeEvents(cyOn, config) {
2121
const on = wrapOn(cyOn)
2222
replayPlugin(on, config, {
23-
upload: true,
2423
apiKey: process.env.REPLAY_API_KEY,
25-
filter: function (recording) {
26-
// upload runtime crashes and any failed tests
27-
return (
28-
recording.status === 'crashed' ||
29-
recording.metadata.test.result === 'failed'
30-
)
31-
},
24+
upload: true,
3225
})
3326
return config
3427
},
@@ -39,21 +32,14 @@ export default defineConfig({
3932
{% /tab %}
4033
{% tab %}
4134

42-
```js
35+
```js {% fileName="playwright.config.js" highlight=[7] %}
4336
import { replayDevices, replayReporter } from "@replayio/playwright";
4437

4538
const config: PlaywrightTestConfig = {
4639
reporter: [
4740
replayReporter({
4841
apiKey: process.env.REPLAY_API_KEY,
4942
upload: true,
50-
filter: function (recording) {
51-
// upload runtime crashes and any failed tests
52-
return (
53-
recording.status === "crashed" ||
54-
recording.metadata.test.result === "failed"
55-
);
56-
},
5743
}),
5844
["line"],
5945
],
@@ -64,32 +50,29 @@ const config: PlaywrightTestConfig = {
6450
},
6551
],
6652
};
53+
6754
export default config;
6855
```
6956

7057
{% /tab %}
7158
{% /tabs %}
7259

73-
## Upload failed and flaky Cypress tests
60+
## Upload failed tests only
61+
62+
To upload recordings only for failed tests use `statusThreshold` option:
7463

75-
By default, all test replays are uploaded no matter the result. If you want to upload failed and flaky tests, you can use the `filter` property in the plugin configuration:
64+
{% tabs labels=["cypress", "playwright"] %}
65+
{% tab %}
7666

77-
```js
67+
```js {% fileName="cypress.config.js" highlight=[7,8,9] %}
7868
export default defineConfig({
7969
e2e: {
8070
setupNodeEvents(cyOn, config) {
8171
const on = wrapOn(cyOn)
8272
replayPlugin(on, config, {
83-
upload: true,
8473
apiKey: process.env.REPLAY_API_KEY,
85-
filter: function (recording) {
86-
// upload runtime crashes and recordings with any tests that failed
87-
return (
88-
recording.status === 'crashed' ||
89-
recording.metadata.test.tests.some(
90-
(test) => test.result === 'failed',
91-
)
92-
)
74+
upload: {
75+
statusThreshold: 'failed',
9376
},
9477
})
9578
return config
@@ -98,23 +81,52 @@ export default defineConfig({
9881
})
9982
```
10083

101-
## Upload only for the primary branch
84+
{% /tab %}
85+
{% tab %}
10286

103-
The recording metadata includes some details about the source control including the repository and branch name which can also be used to filter your uploads. The example below uploads all recordings from the `main` branch:
87+
```js {% fileName="playwright.config.js" highlight=[7,8,9] %}
88+
import { replayDevices, replayReporter } from "@replayio/playwright";
89+
90+
const config: PlaywrightTestConfig = {
91+
reporter: [
92+
replayReporter({
93+
apiKey: process.env.REPLAY_API_KEY,
94+
upload: {
95+
statusThreshold: "failed"
96+
},
97+
}),
98+
["line"],
99+
],
100+
projects: [
101+
{
102+
name: "replay-chromium",
103+
use: { ...replayDevices["Replay Chromium"] },
104+
},
105+
],
106+
};
107+
108+
export default config;
109+
```
110+
111+
{% /tab %}
112+
{% /tabs %}
113+
114+
## Upload failed and flaky tests
115+
116+
To upload recordings for failed and flaky tests use `statusThreshold` option:
104117

105118
{% tabs labels=["cypress", "playwright"] %}
106119
{% tab %}
107120

108-
```js
121+
```js {% fileName="cypress.config.js" highlight=[7,8,9] %}
109122
export default defineConfig({
110123
e2e: {
111124
setupNodeEvents(cyOn, config) {
112125
const on = wrapOn(cyOn)
113126
replayPlugin(on, config, {
114-
upload: true,
115127
apiKey: process.env.REPLAY_API_KEY,
116-
filter: function (recording) {
117-
return recording.metadata.source.branch === 'main'
128+
upload: {
129+
statusThreshold: 'failed-and-flaky',
118130
},
119131
})
120132
return config
@@ -126,17 +138,16 @@ export default defineConfig({
126138
{% /tab %}
127139
{% tab %}
128140

129-
```js
141+
```js {% fileName="playwright.config.js" highlight=[7,8,9] %}
130142
import { replayDevices, replayReporter } from "@replayio/playwright";
131143

132144
const config: PlaywrightTestConfig = {
133145
reporter: [
134146
replayReporter({
135147
apiKey: process.env.REPLAY_API_KEY,
136-
upload: true,
137-
filter: function (recording) {
138-
return recording.metadata.source.branch === "main";
139-
},
148+
upload: {
149+
statusThreshold: "failed-and-flaky"
150+
},
140151
}),
141152
["line"],
142153
],
@@ -147,42 +158,35 @@ const config: PlaywrightTestConfig = {
147158
},
148159
],
149160
};
161+
150162
export default config;
151163
```
152164

153165
{% /tab %}
154166
{% /tabs %}
155167

156-
## Upload some passing runs
168+
## Upload only for the primary branch
157169

158-
If you've adopted one the configurations above but would also like to periodically upload all replays for a test run, you can add a condition to the filter that returns `true` for a given test run id. This is only one possible implementation of this approach and you're welcome to adopt others such as using external environment variables.
170+
Many CI providers provide an environment variable that references the current branch name.
171+
172+
- [CircleCI](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables): `$CIRCLE_BRANCH`
173+
- [GitLab](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html): `$CI_COMMIT_REF_NAME`
174+
- [Semaphore](https://docs.semaphoreci.com/ci-cd-environment/environment-variables/): `$SEMAPHORE_GIT_BRANCH`
175+
- [Travis](https://docs.travis-ci.com/user/environment-variables/#default-environment-variables): `$TRAVIS_BRANCH`
176+
177+
GitHub [stores this value in a default variable](https://docs.github.com/en/actions/learn-github-actions/variables) named `GITHUB_BASE_REF` that can be passed along as [part of a Workflow](https://docs.github.com/en/actions/learn-github-actions/variables#defining-environment-variables-for-a-single-workflow) and then referenced in the test config like so:
159178

160179
{% tabs labels=["cypress", "playwright"] %}
161180
{% tab %}
162181

163-
```js
164-
const convertStringToInt = (string) =>
165-
string.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0)
166-
182+
```js {% fileName="cypress.config.js" highlight=[7] %}
167183
export default defineConfig({
168184
e2e: {
169185
setupNodeEvents(cyOn, config) {
170186
const on = wrapOn(cyOn)
171187
replayPlugin(on, config, {
172-
upload: true,
173188
apiKey: process.env.REPLAY_API_KEY,
174-
filter: function (recording) {
175-
// randomly upload 10% of all test runs
176-
if (convertStringToInt(r.metadata.test.run.id) % 10 === 1) {
177-
return true
178-
}
179-
180-
// upload runtime crashes and any failed tests
181-
return (
182-
recording.status === 'crashed' ||
183-
recording.metadata.test.result === 'failed'
184-
)
185-
},
189+
upload: process.env.BRANCH_NAME === 'main',
186190
})
187191
return config
188192
},
@@ -193,29 +197,14 @@ export default defineConfig({
193197
{% /tab %}
194198
{% tab %}
195199

196-
```js
200+
```js {% fileName="playwright.config.js" highlight=[7] %}
197201
import { replayDevices, replayReporter } from "@replayio/playwright";
198202

199-
const convertStringToInt = string =>
200-
string.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
201-
202203
const config: PlaywrightTestConfig = {
203204
reporter: [
204205
replayReporter({
205206
apiKey: process.env.REPLAY_API_KEY,
206-
upload: true,
207-
filter: function (recording) {
208-
// randomly upload 10% of all test runs
209-
if (convertStringToInt(r.metadata.test.run.id) % 10 === 1) {
210-
return true;
211-
}
212-
213-
// upload runtime crashes and any failed tests
214-
return (
215-
recording.status === "crashed" ||
216-
recording.metadata.test.result === "failed"
217-
);
218-
},
207+
upload: process.env.BRANCH_NAME === "main"
219208
}),
220209
["line"],
221210
],
@@ -226,38 +215,97 @@ const config: PlaywrightTestConfig = {
226215
},
227216
],
228217
};
218+
229219
export default config;
230220
```
231221

232222
{% /tab %}
233223
{% /tabs %}
234224

235-
## Using GitHub Action
236-
237-
Alternatively, you can upload your replays in a separate step using our [GitHub upload action](https://github.com/replayio/action-upload). To filter which replays to upload, you can use [JSONata filtering functions](https://docs.jsonata.org/higher-order-functions#filter).
238-
239-
```yml {% fileName=".github/workflows/e2e.yml" lineNumbers=true highlight=[19] %}
240-
name: Replay tests
241-
on:
242-
pull_request:
243-
push:
244-
branches: [main]
245-
jobs:
246-
cypress-run:
247-
runs-on: ubuntu-22.04
248-
steps:
249-
- name: Checkout
250-
uses: actions/checkout@v4
251-
- name: Install dependencies
252-
run: npm ci
253-
- name: Install Replay Chromium
254-
run: npx replayio install
255-
- name: Run Playwright tests with Replay Browser
256-
run: npx playwright test --project replay-chromium --reporter=@replayio/playwright/reporter,line
257-
- name: Upload replays
258-
if: ${{ always() }}
259-
uses: replayio/[email protected]
260-
with:
261-
api-key: ${{ secrets.REPLAY_API_KEY }}
262-
filter: ${{ 'function($v) { $v.metadata.test.result = "failed" }' }}
225+
## Reducing the number of uploaded recordings
226+
227+
Use the advanced upload options to reduce the number of recordings that are uploaded. When this option is enabled, only one recording will be uploaded for any passing or failing test. For flaky tests, two recordings will be uploaded– the passing test and one of the failed attempts.
228+
229+
```js {% fileName="playwright.config.js" highlight=[7,8,9] %}
230+
import { replayDevices, replayReporter } from "@replayio/playwright";
231+
232+
const config: PlaywrightTestConfig = {
233+
reporter: [
234+
replayReporter({
235+
apiKey: process.env.REPLAY_API_KEY,
236+
upload: {
237+
minimizeUploads: true,
238+
},
239+
}),
240+
["line"],
241+
],
242+
projects: [
243+
{
244+
name: "replay-chromium",
245+
use: { ...replayDevices["Replay Chromium"] },
246+
},
247+
],
248+
};
249+
250+
export default config;
251+
```
252+
253+
{% callout %}
254+
Note this option is only available for tests recorded with Playwright
255+
{% /callout %}
256+
257+
## Combining options
258+
259+
You can combine advanced upload options to e.g. only upload a single recording and only for a failing test.
260+
261+
{% tabs labels=["cypress", "playwright"] %}
262+
{% tab %}
263+
264+
```js {% fileName="cypress.config.js" highlight=[7,8,9,10] %}
265+
export default defineConfig({
266+
e2e: {
267+
setupNodeEvents(cyOn, config) {
268+
const on = wrapOn(cyOn)
269+
replayPlugin(on, config, {
270+
apiKey: process.env.REPLAY_API_KEY,
271+
upload: {
272+
minimizeUploads: true,
273+
statusThreshold: 'failed',
274+
},
275+
})
276+
return config
277+
},
278+
},
279+
})
280+
```
281+
282+
{% /tab %}
283+
{% tab %}
284+
285+
```js {% fileName="playwright.config.js" highlight=[7,8,9,10] %}
286+
import { replayDevices, replayReporter } from "@replayio/playwright";
287+
288+
const config: PlaywrightTestConfig = {
289+
reporter: [
290+
replayReporter({
291+
apiKey: process.env.REPLAY_API_KEY,
292+
upload: {
293+
minimizeUploads: true,
294+
statusThreshold: "failed",
295+
},
296+
}),
297+
["line"],
298+
],
299+
projects: [
300+
{
301+
name: "replay-chromium",
302+
use: { ...replayDevices["Replay Chromium"] },
303+
},
304+
],
305+
};
306+
307+
export default config;
263308
```
309+
310+
{% /tab %}
311+
{% /tabs %}

0 commit comments

Comments
 (0)