Repository: elastic/synthetics
Pull request #706 (2023-02-22 16:08:31)

enable use of custom data-test-id
With this we can provide a custom data-test id like `data-test-subj`, will make life easier with kibana tests specifically. 

apmmachine: 
## :green_heart: Build Succeeded


<!-- BUILD BADGES-->
> _the below badges are clickable and redirect to their specific view in the CI or DOCS_
[![Pipeline View](https://img.shields.io/badge/pipeline-pipeline%20-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-706/detail/PR-706/1//pipeline) [![Test View](https://img.shields.io/badge/test-test-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-706/detail/PR-706/1//tests) [![Changes](https://img.shields.io/badge/changes-changes-green)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-706/detail/PR-706/1//changes) [![Artifacts](https://img.shields.io/badge/artifacts-artifacts-yellow)](https://apm-ci.elastic.co/blue/organizations/jenkins/apm-agent-rum%2Felastic-synthetics%2FPR-706/detail/PR-706/1//artifacts) [![preview](https://img.shields.io/badge/docs-preview-yellowgreen)](http://synthetics_706.docs-preview.app.elstc.co/diff)  [![preview](https://img.shields.io/badge/elastic-observability-blue)](https://ci-stats.elastic.co/app/apm/services/apm-ci/transactions/view?rangeFrom=2023-02-22T15:58:46.030Z&rangeTo=2023-02-22T16:18:46.030Z&transactionName=BUILD+apm-agent-rum%2Felastic-synthetics%2FPR-%7Bnumber%7D&transactionType=job&latencyAggregationType=avg&traceId=72d40dbfe3f917187d4503e0aa7a155e&transactionId=75a52bb0f0f31b2b)

<!-- BUILD SUMMARY-->
<details><summary>Expand to view the summary</summary>
<p>

#### Build stats




* Start Time: 2023-02-22T16:08:46.030+0000


* Duration: 14 min 50 sec




#### Test stats :test_tube:

| Test         | Results                         |
| ------------ | :-----------------------------: |
| Failed       | 0  |
| Passed       | 203  |
| Skipped      | 12 |
| Total        | 215   |


</p>
</details>

<!-- TEST RESULTS IF ANY-->


<!-- STEPS ERRORS IF ANY -->














## :robot: GitHub comments

<details><summary>Expand to view the GitHub comments</summary>
<p>

To re-run your PR in the CI, just comment with:



- `/test` : Re-trigger the build.




</p>
</details>

<!--COMMENT_GENERATED_WITH_ID_comment.id-->
shahzad31: > @shahzad31 Whats the motivation behind this change? I have couple of questions on this
> 
> 1. why cant Kibana set these attributes on `beforeAll` hook?
> 2. Also, since you are doing this on the overall journey, How would it help in the Kibana context since the whole journey could contain multiple elements with these test attributes?

setting it as  `beforeAll` will not work for inline scripts.  Plus we will have to import selectors from playwright-chromium directly. Seems hack to me going outside agent package.

`Also, since you are doing this on the overall journey, How would it help in the Kibana context since the whole journey could contain multiple elements with these test attributes?
`
can you please explain this question?


shahzad31: > @shahzad31 Whats the motivation behind this change? I have couple of questions on this

basic motivation is ability to use `page.getByTestId` selector.



Patch:
diff --git a/src/common_types.ts b/src/common_types.ts
index ce3ddd2..10c4192 100644
--- a/src/common_types.ts
+++ b/src/common_types.ts
@@ -254,7 +254,8 @@ export type ProjectSettings = {
   space: string;
 };
 
-export type PlaywrightOptions = LaunchOptions & BrowserContextOptions;
+export type PlaywrightOptions = LaunchOptions &
+  BrowserContextOptions & { testIdAttribute?: string };
 export type SyntheticsConfig = {
   params?: Params;
   playwrightOptions?: PlaywrightOptions;
diff --git a/src/core/gatherer.ts b/src/core/gatherer.ts
index 611a7dc..b5a28c9 100644
--- a/src/core/gatherer.ts
+++ b/src/core/gatherer.ts
@@ -28,6 +28,7 @@ import {
   ChromiumBrowser,
   BrowserContext,
   request as apiRequest,
+  selectors,
 } from 'playwright-chromium';
 import { PluginManager } from '../plugins';
 import { log } from './logger';
@@ -64,6 +65,10 @@ export class Gatherer {
     });
     Gatherer.setNetworkConditions(context, networkConditions);
 
+    if (playwrightOptions?.testIdAttribute) {
+      selectors.setTestIdAttribute(playwrightOptions.testIdAttribute);
+    }
+
     const page = await context.newPage();
     const client = await context.newCDPSession(page);
     const request = await apiRequest.newContext({ ...playwrightOptions });


Test patch:
diff --git a/__tests__/core/gatherer.test.ts b/__tests__/core/gatherer.test.ts
index 8dbbe7f..8992e11 100644
--- a/__tests__/core/gatherer.test.ts
+++ b/__tests__/core/gatherer.test.ts
@@ -164,6 +164,41 @@ describe('Gatherer', () => {
     });
   });
 
+  describe('Set Test ID Attribute', () => {
+    it('uses default when not set', async () => {
+      const driver = await Gatherer.setupDriver({
+        wsEndpoint,
+      });
+      const { page } = driver;
+      await page.goto(server.TEST_PAGE);
+      await page.setContent(
+        '<a target=_blank rel=noopener href="/popup.html" data-testid="username-button">Click me</a>'
+      );
+      expect(await page.getByTestId('username-button').isVisible()).toEqual(
+        true
+      );
+      await Gatherer.dispose(driver);
+      await Gatherer.stop();
+    });
+
+    it('uses custom when provided', async () => {
+      const driver = await Gatherer.setupDriver({
+        wsEndpoint,
+        playwrightOptions: { testIdAttribute: 'data-test-subj' },
+      });
+      const { page } = driver;
+      await page.goto(server.TEST_PAGE);
+      await page.setContent(
+        '<a target=_blank rel=noopener href="/popup.html" data-test-subj="username-button">Click me</a>'
+      );
+      expect(await page.getByTestId('username-button').isVisible()).toEqual(
+        true
+      );
+      await Gatherer.dispose(driver);
+      await Gatherer.stop();
+    });
+  });
+
   describe('Network emulation', () => {
     const networkConditions = {
       downloadThroughput: megabitsToBytes(3),