[Recorder] turn injected tests into unit tests (part 2)

Interaction tests are removed with this CL.

Bug: 402372244
Change-Id: Ia6fb66f9765b576dac2ddec0a5f270e865e69f37
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6343238
Auto-Submit: Alex Rudenko <alexrudenko@chromium.org>
Commit-Queue: Nikolay Vitkov <nvitkov@chromium.org>
Reviewed-by: Nikolay Vitkov <nvitkov@chromium.org>
diff --git a/front_end/panels/recorder/injected.test.ts b/front_end/panels/recorder/injected.test.ts
index 6f3f470..a87c26e 100644
--- a/front_end/panels/recorder/injected.test.ts
+++ b/front_end/panels/recorder/injected.test.ts
@@ -84,4 +84,176 @@
       ]
     ]);
   });
+
+  it('should get selectors for elements with custom selector attributes', async () => {
+    const window = await createSandbox();
+    const targets = [
+      ...window.document.querySelectorAll('.custom-selector-attribute'),
+      window.document.querySelector('#shadow-root-with-custom-selectors')?.shadowRoot?.querySelector('button') as
+          HTMLButtonElement,
+    ];
+    const selectors = targets.map(
+        window.DevToolsRecorder.recordingClientForTesting.getSelectors,
+    );
+    assert.deepEqual(selectors, [
+      [
+        [
+          '[data-testid=\'unique\']',
+        ],
+        [
+          'xpath///*[@data-testid="unique"]',
+        ],
+        [
+          'pierce/[data-testid=\'unique\']',
+        ]
+      ],
+      [
+        ['[data-testid=\'\\31 23456789\']'], ['xpath///*[@data-testid="123456789"]'],
+        ['pierce/[data-testid=\'\\31 23456789\']'], ['text/Custom selector (invalid']
+      ],
+      [
+        ['[data-qa=\'custom-id\']', '[data-testid=\'shadow\\ button\']'], ['pierce/[data-testid=\'shadow\\ button\']'],
+        ['text/Shadow button']
+      ]
+    ]);
+  });
+
+  it('should get selectors for shadow root elements', async () => {
+    const window = await createSandbox();
+    const selectors = window.DevToolsRecorder.recordingClientForTesting.getSelectors(
+        window.document.querySelector('main')
+            ?.querySelector('shadow-css-selector-element')
+            ?.shadowRoot?.querySelector('#insideShadowRoot')!,
+    );
+    assert.deepEqual(selectors, [
+      ['main > shadow-css-selector-element', '#insideShadowRoot'],
+      ['pierce/main > shadow-css-selector-element', 'pierce/#insideShadowRoot']
+    ]);
+  });
+
+  it('should get an ARIA selector for shadow root elements', async () => {
+    const window = await createSandbox();
+    const selectors = window.DevToolsRecorder.recordingClientForTesting.getSelectors(
+        window.document.querySelector('[aria-role="main"]')
+            ?.querySelector('shadow-aria-selector-element')
+            ?.shadowRoot?.querySelector('button')!,
+    );
+    assert.deepEqual(selectors, [
+      ['aria/[role="main"]', 'aria/login'], ['div:nth-of-type(2) > shadow-aria-selector-element', 'button'],
+      ['pierce/div:nth-of-type(2) > shadow-aria-selector-element', 'pierce/button']
+    ]);
+  });
+
+  it('should not get an ARIA selector if the target element has no name or role', async () => {
+    const window = await createSandbox();
+    const selectors = window.DevToolsRecorder.recordingClientForTesting.getSelectors(
+        window.document.querySelector('#no-aria-name-or-role')!);
+    assert.deepEqual(
+        selectors,
+        [['#no-aria-name-or-role'], ['xpath///*[@id="no-aria-name-or-role"]'], ['pierce/#no-aria-name-or-role']]);
+  });
+
+  describe('CSS selectors', () => {
+    it('should query CSS selectors', async () => {
+      const window = await createSandbox();
+      const results = [
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                ['[data-qa=custom-id]', '[data-testid=shadow\\ button]'],
+                )
+            .length,
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                ['[data-qa=custom-id]'],
+                )
+            .length,
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                '[data-qa=custom-id]',
+                )
+            .length,
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                '.doesnotexist',
+                )
+            .length,
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                ['[data-qa=custom-id]', '.doesnotexist'],
+                )
+            .length,
+        window.DevToolsRecorder.recordingClientForTesting
+            .queryCSSSelectorAllForTesting(
+                ['#notunique'],
+                )
+            .length,
+      ];
+      assert.deepEqual(results, [1, 1, 1, 0, 0, 2]);
+    });
+
+    it('should return not-optimized CSS selectors for duplicate elements', async () => {
+      const window = await createSandbox();
+      const selectors =
+          window.DevToolsRecorder.recordingClientForTesting.getSelectors(window.document.querySelector('#notunique')!);
+      assert.deepEqual(selectors, [
+        ['div:nth-of-type(3) > div:nth-of-type(2)'], ['xpath///*[@id="notunique"]'],
+        ['pierce/div:nth-of-type(3) > div:nth-of-type(2)']
+      ]);
+    });
+  });
+
+  describe('Text selectors', () => {
+    const getSelectorOfButtonWithLength = async (length: number) => {
+      const window = await createSandbox();
+      const selector = `#buttonWithLength${length}`;
+      const target = window.document.querySelector(selector);
+      if (!target) {
+        throw new Error(`${selector} could not be found.`);
+      }
+      if (target.innerHTML.length !== length) {
+        throw new Error(`${selector} is not of length ${length}`);
+      }
+      return window.DevToolsRecorder.recordingClientForTesting.getTextSelector(
+          target,
+      );
+    };
+    const MINIMUM_LENGTH = 12;
+    const MAXIMUM_LENGTH = 64;
+    const SAME_PREFIX_TEXT_LENGTH = 32;
+
+    it('should return a text selector for elements < minimum length', async () => {
+      const selectors = await getSelectorOfButtonWithLength(MINIMUM_LENGTH - 1);
+      assert.deepEqual(selectors, ['text/length a 11']);
+    });
+    it('should return a text selector for elements == minimum length', async () => {
+      const selectors = await getSelectorOfButtonWithLength(MINIMUM_LENGTH);
+      assert.deepEqual(selectors, ['text/length aa 12']);
+    });
+    it('should return a text selector for elements == maximum length', async () => {
+      const selectors = await getSelectorOfButtonWithLength(MAXIMUM_LENGTH);
+      assert.deepEqual(selectors, ['text/length aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaa 64']);
+    });
+    it('should not return a text selector for elements > maximum length', async () => {
+      const selectors = await getSelectorOfButtonWithLength(MAXIMUM_LENGTH + 1);
+      assert.isUndefined(selectors);
+    });
+    it('should return a text selector correctly with same prefix elements', async () => {
+      let selectors = await getSelectorOfButtonWithLength(
+          SAME_PREFIX_TEXT_LENGTH,
+      );
+      assert.deepEqual(selectors, ['text/length aaaaaaaaa aaaaaaaaa aa 32']);
+      selectors = await getSelectorOfButtonWithLength(
+          SAME_PREFIX_TEXT_LENGTH + 1,
+      );
+      assert.deepEqual(selectors, ['text/length aaaaaaaaa aaaaaaaaa aaa 33']);
+    });
+    it('should trim text selectors', async () => {
+      const window = await createSandbox();
+      assert.deepEqual(
+          window.DevToolsRecorder.recordingClientForTesting.getTextSelector(
+              window.document.querySelector('#buttonWithNewLines')!,
+              ),
+          ['text/with newlines']);
+    });
+  });
 });
diff --git a/front_end/ui/components/docs/recorder_injected/BUILD.gn b/front_end/ui/components/docs/recorder_injected/BUILD.gn
index dc3b8e3..7517391 100644
--- a/front_end/ui/components/docs/recorder_injected/BUILD.gn
+++ b/front_end/ui/components/docs/recorder_injected/BUILD.gn
@@ -5,18 +5,7 @@
 import("../../../../../scripts/build/ninja/copy.gni")
 import("../../../../../scripts/build/typescript/typescript.gni")
 
-ts_library("ts") {
-  testonly = true
-  sources = [ "basic.ts" ]
-  deps = [
-    "../../../../panels/recorder/injected:bundle",
-    "../../../../testing",
-  ]
-}
-
 copy_to_gen("recorder_injected") {
   testonly = true
   sources = [ "basic.html" ]
-
-  deps = [ ":ts" ]
 }
diff --git a/front_end/ui/components/docs/recorder_injected/basic.html b/front_end/ui/components/docs/recorder_injected/basic.html
index dd8d69c..082fde7 100644
--- a/front_end/ui/components/docs/recorder_injected/basic.html
+++ b/front_end/ui/components/docs/recorder_injected/basic.html
@@ -96,6 +96,5 @@
 
     <div id="notunique"></div>
     <div id="notunique"></div>
-    <script type="module" src="./basic.js"></script>
   </body>
 </html>
diff --git a/front_end/ui/components/docs/recorder_injected/basic.ts b/front_end/ui/components/docs/recorder_injected/basic.ts
deleted file mode 100644
index a43df15..0000000
--- a/front_end/ui/components/docs/recorder_injected/basic.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import '../../../../panels/recorder/injected/injected.js';
diff --git a/test/interactions/BUILD.gn b/test/interactions/BUILD.gn
index 2c6edbe..fd5877a 100644
--- a/test/interactions/BUILD.gn
+++ b/test/interactions/BUILD.gn
@@ -17,7 +17,6 @@
     "helpers",
     "panels/explain",
     "panels/performance/timeline",
-    "panels/recorder/injected",
     "text_editor",
     "tree_outline",
     "ui/components",
diff --git a/test/interactions/panels/recorder/injected/BUILD.gn b/test/interactions/panels/recorder/injected/BUILD.gn
deleted file mode 100644
index 8281df5..0000000
--- a/test/interactions/panels/recorder/injected/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2023 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("../../../../../scripts/build/typescript/typescript.gni")
-
-node_ts_library("injected") {
-  sources = [ "injected_test.ts" ]
-
-  deps = [
-    "../../../../../front_end/panels/recorder/injected:bundle",
-    "../../../../../front_end/panels/recorder/models:bundle",
-    "../../../../../test/e2e/helpers",
-    "../../../../../test/interactions/helpers",
-    "../../../../../test/shared",
-  ]
-}
diff --git a/test/interactions/panels/recorder/injected/injected_test.json b/test/interactions/panels/recorder/injected/injected_test.json
deleted file mode 100644
index 2d0a972..0000000
--- a/test/interactions/panels/recorder/injected/injected_test.json
+++ /dev/null
@@ -1,108 +0,0 @@
-{
-  "Injected should get selectors for an element - 1": [
-    [
-      "#buttonNoARIA"
-    ],
-    [
-      "xpath///*[@id=\"buttonNoARIA\"]"
-    ],
-    [
-      "pierce/#buttonNoARIA"
-    ]
-  ],
-  "Injected should get selectors for elements with custom selector attributes - 1": [
-    [
-      [
-        "[data-testid='unique']"
-      ],
-      [
-        "xpath///*[@data-testid=\"unique\"]"
-      ],
-      [
-        "pierce/[data-testid='unique']"
-      ]
-    ],
-    [
-      [
-        "[data-testid='\\31 23456789']"
-      ],
-      [
-        "xpath///*[@data-testid=\"123456789\"]"
-      ],
-      [
-        "pierce/[data-testid='\\31 23456789']"
-      ],
-      [
-        "text/Custom selector (invalid"
-      ]
-    ],
-    [
-      [
-        "[data-qa='custom-id']",
-        "[data-testid='shadow\\ button']"
-      ],
-      [
-        "pierce/[data-testid='shadow\\ button']"
-      ],
-      [
-        "text/Shadow button"
-      ]
-    ]
-  ],
-  "Injected should get selectors for shadow root elements - 1": [
-    [
-      "main > shadow-css-selector-element",
-      "#insideShadowRoot"
-    ],
-    [
-      "pierce/main > shadow-css-selector-element",
-      "pierce/#insideShadowRoot"
-    ]
-  ],
-  "Injected should get an ARIA selector for shadow root elements - 1": [
-    [
-      "aria/[role=\"main\"]",
-      "aria/login"
-    ],
-    [
-      "div:nth-of-type(2) > shadow-aria-selector-element",
-      "button"
-    ],
-    [
-      "pierce/div:nth-of-type(2) > shadow-aria-selector-element",
-      "pierce/button"
-    ]
-  ],
-  "Injected should not get an ARIA selector if the target element has no name or role - 1": [
-    [
-      "#no-aria-name-or-role"
-    ],
-    [
-      "xpath///*[@id=\"no-aria-name-or-role\"]"
-    ],
-    [
-      "pierce/#no-aria-name-or-role"
-    ]
-  ],
-  "Injected CSS selectors should return not-optimized CSS selectors for duplicate elements - 1": [
-    "div:nth-of-type(3) > div:nth-of-type(2)"
-  ],
-  "Injected Text selectors should return a text selector for elements < minimum length - 1": [
-    "text/length a 11"
-  ],
-  "Injected Text selectors should return a text selector for elements == minimum length - 1": [
-    "text/length aa 12"
-  ],
-  "Injected Text selectors should return a text selector for elements == maximum length - 1": [
-    "text/length aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaa 64"
-  ],
-  "Injected Text selectors should return a text selector correctly with same prefix elements - Smaller": [
-    "text/length aaaaaaaaa aaaaaaaaa aa 32"
-  ],
-  "Injected Text selectors should return a text selector correctly with same prefix elements - Larger": [
-    "text/length aaaaaaaaa aaaaaaaaa aaa 33"
-  ],
-  "Injected Text selectors should trim text selectors - 1": [
-    "text/with newlines"
-  ]
-}
\ No newline at end of file
diff --git a/test/interactions/panels/recorder/injected/injected_test.ts b/test/interactions/panels/recorder/injected/injected_test.ts
deleted file mode 100644
index 5afaeef..0000000
--- a/test/interactions/panels/recorder/injected/injected_test.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2023 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assert} from 'chai';
-
-import type {DevToolsRecorder} from '../../../../../front_end/panels/recorder/injected/injected.js';
-import type {Schema} from '../../../../../front_end/panels/recorder/models/models.js';
-import {
-  loadComponentDocExample,
-} from '../../../../../test/interactions/helpers/shared.js';
-import {getBrowserAndPages} from '../../../../../test/shared/helper.js';
-import {assertMatchesJSONSnapshot} from '../../../../../test/shared/snapshots.js';
-
-describe('Injected', () => {
-  beforeEach(async () => {
-    await loadComponentDocExample('recorder_injected/basic.html');
-
-    const {frontend} = getBrowserAndPages();
-    await frontend.evaluate(() => {
-      (window.DevToolsRecorder as DevToolsRecorder)
-          .startRecording(
-              {
-                // We don't have the access to the actual bindings here. Therefore, the test assumes
-                // that the markup is explicitly annotated with the following attributes.
-                getAccessibleName: (element: Node) => {
-                  if (!('getAttribute' in element)) {
-                    return '';
-                  }
-                  return (element as Element).getAttribute('aria-name') || '';
-                },
-                getAccessibleRole: (element: Node) => {
-                  if (!('getAttribute' in element)) {
-                    return 'generic';
-                  }
-                  return (element as Element).getAttribute('aria-role') || '';
-                },
-              },
-              {
-                debug: false,
-                allowUntrustedEvents: true,
-                selectorTypesToRecord: [
-                  'xpath',
-                  'css',
-                  'text',
-                  'aria',
-                  'pierce',
-                ] as Schema.SelectorType[],
-              },
-          );
-    });
-  });
-
-  afterEach(async () => {
-    const {frontend} = getBrowserAndPages();
-    await frontend.evaluate(() => {
-      window.DevToolsRecorder.stopRecording();
-    });
-  });
-
-  it('should get selectors for an element', async () => {
-    const {frontend} = getBrowserAndPages();
-    const selectors = await frontend.evaluate(() => {
-      const target = document.querySelector('#buttonNoARIA');
-      if (!target) {
-        throw new Error('#buttonNoARIA not found');
-      }
-      return window.DevToolsRecorder.recordingClientForTesting.getSelectors(
-          target,
-      );
-    });
-    assertMatchesJSONSnapshot(selectors);
-  });
-
-  it('should get selectors for elements with custom selector attributes', async () => {
-    const {frontend} = getBrowserAndPages();
-    const selectors = await frontend.evaluate(() => {
-      const targets = [
-        ...document.querySelectorAll('.custom-selector-attribute'),
-        document.querySelector('#shadow-root-with-custom-selectors')?.shadowRoot?.querySelector('button') as
-            HTMLButtonElement,
-      ];
-      return targets.map(
-          window.DevToolsRecorder.recordingClientForTesting.getSelectors,
-      );
-    });
-    assertMatchesJSONSnapshot(selectors);
-  });
-
-  it('should get selectors for shadow root elements', async () => {
-    const {frontend} = getBrowserAndPages();
-    const selectors = await frontend.evaluate(() => {
-      const target = document.querySelector('main')
-                         ?.querySelector('shadow-css-selector-element')
-                         ?.shadowRoot?.querySelector('#insideShadowRoot');
-      if (!target) {
-        throw new Error('#insideShadowRoot is not found');
-      }
-      return window.DevToolsRecorder.recordingClientForTesting.getSelectors(
-          target,
-      );
-    });
-    assertMatchesJSONSnapshot(selectors);
-  });
-
-  it('should get an ARIA selector for shadow root elements', async () => {
-    const {frontend} = getBrowserAndPages();
-    const selectors = await frontend.evaluate(() => {
-      const target = document.querySelector('[aria-role="main"]')
-                         ?.querySelector('shadow-aria-selector-element')
-                         ?.shadowRoot?.querySelector('button');
-      if (!target) {
-        throw new Error('button is not found');
-      }
-      return window.DevToolsRecorder.recordingClientForTesting.getSelectors(
-          target,
-      );
-    });
-    assertMatchesJSONSnapshot(selectors);
-  });
-
-  it('should not get an ARIA selector if the target element has no name or role', async () => {
-    const {frontend} = getBrowserAndPages();
-    const selectors = await frontend.evaluate(() => {
-      const target = document.querySelector('#no-aria-name-or-role');
-      if (!target) {
-        throw new Error('button is not found');
-      }
-      return window.DevToolsRecorder.recordingClientForTesting.getSelectors(
-          target,
-      );
-    });
-    assertMatchesJSONSnapshot(selectors);
-  });
-
-  describe('CSS selectors', () => {
-    it('should query CSS selectors', async () => {
-      const {frontend} = getBrowserAndPages();
-      const results = await frontend.evaluate(() => {
-        return [
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  ['[data-qa=custom-id]', '[data-testid=shadow\\ button]'],
-                  )
-              .length,
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  ['[data-qa=custom-id]'],
-                  )
-              .length,
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  '[data-qa=custom-id]',
-                  )
-              .length,
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  '.doesnotexist',
-                  )
-              .length,
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  ['[data-qa=custom-id]', '.doesnotexist'],
-                  )
-              .length,
-          window.DevToolsRecorder.recordingClientForTesting
-              .queryCSSSelectorAllForTesting(
-                  ['#notunique'],
-                  )
-              .length,
-        ];
-      });
-      assert.deepEqual(results, [1, 1, 1, 0, 0, 2]);
-    });
-
-    it('should return not-optimized CSS selectors for duplicate elements', async () => {
-      const {frontend} = getBrowserAndPages();
-      const selector = await frontend.evaluate(() => {
-        const target = document.querySelector('#notunique');
-        if (!target) {
-          throw new Error('#notunique is not found');
-        }
-        return window.DevToolsRecorder.recordingClientForTesting.getCSSSelector(
-            target,
-        );
-      });
-      assertMatchesJSONSnapshot(selector);
-    });
-  });
-
-  describe('Text selectors', () => {
-    const getSelectorOfButtonWithLength = (length: number) => {
-      const {frontend} = getBrowserAndPages();
-      return frontend.evaluate(length => {
-        const selector = `#buttonWithLength${length}`;
-        const target = document.querySelector(selector);
-        if (!target) {
-          throw new Error(`${selector} could not be found.`);
-        }
-        if (target.innerHTML.length !== length) {
-          throw new Error(`${selector} is not of length ${length}`);
-        }
-        return window.DevToolsRecorder.recordingClientForTesting.getTextSelector(
-            target,
-        );
-      }, length);
-    };
-    const MINIMUM_LENGTH = 12;
-    const MAXIMUM_LENGTH = 64;
-    const SAME_PREFIX_TEXT_LENGTH = 32;
-
-    it('should return a text selector for elements < minimum length', async () => {
-      const selectors = await getSelectorOfButtonWithLength(MINIMUM_LENGTH - 1);
-      assertMatchesJSONSnapshot(selectors);
-    });
-    it('should return a text selector for elements == minimum length', async () => {
-      const selectors = await getSelectorOfButtonWithLength(MINIMUM_LENGTH);
-      assertMatchesJSONSnapshot(selectors);
-    });
-    it('should return a text selector for elements == maximum length', async () => {
-      const selectors = await getSelectorOfButtonWithLength(MAXIMUM_LENGTH);
-      assertMatchesJSONSnapshot(selectors);
-    });
-    it('should not return a text selector for elements > maximum length', async () => {
-      const selectors = await getSelectorOfButtonWithLength(MAXIMUM_LENGTH + 1);
-      assert.isUndefined(selectors);
-    });
-    it('should return a text selector correctly with same prefix elements', async () => {
-      let selectors = await getSelectorOfButtonWithLength(
-          SAME_PREFIX_TEXT_LENGTH,
-      );
-      assertMatchesJSONSnapshot(selectors, {name: 'Smaller'});
-      selectors = await getSelectorOfButtonWithLength(
-          SAME_PREFIX_TEXT_LENGTH + 1,
-      );
-      assertMatchesJSONSnapshot(selectors, {name: 'Larger'});
-    });
-    it('should trim text selectors', async () => {
-      const {frontend} = getBrowserAndPages();
-      const selectors = await frontend.evaluate(() => {
-        const selector = '#buttonWithNewLines';
-        const target = document.querySelector(selector);
-        if (!target) {
-          throw new Error(`${selector} could not be found.`);
-        }
-        return window.DevToolsRecorder.recordingClientForTesting.getTextSelector(
-            target,
-        );
-      });
-      assertMatchesJSONSnapshot(selectors);
-    });
-  });
-});