diff --git a/packages/playwright-core/src/server/injected/highlight.css b/packages/playwright-core/src/server/injected/highlight.css
index 9ee0370720..5126f74c4f 100644
--- a/packages/playwright-core/src/server/injected/highlight.css
+++ b/packages/playwright-core/src/server/injected/highlight.css
@@ -20,6 +20,11 @@
color: #333;
}
+svg {
+ position: absolute;
+ height: 0;
+}
+
x-pw-tooltip {
backdrop-filter: blur(5px);
background-color: white;
@@ -122,16 +127,10 @@ x-pw-tool-gripper:active {
}
x-pw-tool-gripper > x-div {
- width: 100%;
- height: 100%;
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- -webkit-mask-size: 20px;
- mask-repeat: no-repeat;
- mask-position: center;
- mask-size: 16px;
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ width: 16px;
+ height: 16px;
+ margin: 6px 4px;
+ clip-path: url(#x-pw-gripper-icon);
background-color: #555555;
}
@@ -169,14 +168,9 @@ x-pw-tool-item.active:not(.disabled):hover {
}
x-pw-tool-item > x-div {
- width: 100%;
- height: 100%;
- -webkit-mask-repeat: no-repeat;
- -webkit-mask-position: center;
- -webkit-mask-size: 20px;
- mask-repeat: no-repeat;
- mask-position: center;
- mask-size: 16px;
+ width: 16px;
+ height: 16px;
+ margin: 6px;
background-color: #3a3a3a;
}
@@ -203,51 +197,41 @@ x-pw-tool-item.accept > x-div {
x-pw-tool-item.record > x-div {
/* codicon: circle-large-filled */
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-record-icon);
}
x-pw-tool-item.pick-locator > x-div {
/* codicon: inspect */
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-pick-locator-icon);
}
x-pw-tool-item.text > x-div {
/* codicon: whole-word */
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-text-icon);
}
x-pw-tool-item.visibility > x-div {
/* codicon: eye */
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-visibility-icon);
}
x-pw-tool-item.value > x-div {
/* codicon: symbol-constant */
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-value-icon);
}
x-pw-tool-item.accept > x-div {
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-accept-icon);
}
x-pw-tool-item.cancel > x-div {
- -webkit-mask-image: url("data:image/svg+xml;utf8,");
- mask-image: url("data:image/svg+xml;utf8,");
+ clip-path: url(#x-pw-cancel-icon);
}
x-pw-tool-item.succeeded > x-div {
/* codicon: pass */
- -webkit-mask-image: url("data:image/svg+xml;utf8,") !important;
- mask-image: url("data:image/svg+xml;utf8,") !important;
+ clip-path: url(#x-pw-succeeded-icon);
background-color: #388a34 !important;
- -webkit-mask-size: 18px !important;
- mask-size: 18px !important;
}
x-pw-overlay {
diff --git a/packages/playwright-core/src/server/injected/highlight.ts b/packages/playwright-core/src/server/injected/highlight.ts
index 0487bf04d7..bb8c8fd123 100644
--- a/packages/playwright-core/src/server/injected/highlight.ts
+++ b/packages/playwright-core/src/server/injected/highlight.ts
@@ -75,10 +75,10 @@ export class Highlight {
this._actionPointElement = document.createElement('x-pw-action-point');
this._actionPointElement.setAttribute('hidden', 'true');
this._glassPaneShadow = this._glassPaneElement.attachShadow({ mode: this._isUnderTest ? 'open' : 'closed' });
+ const sheet = new CSSStyleSheet();
+ sheet.replaceSync(highlightCSS);
+ this._glassPaneShadow.adoptedStyleSheets = [sheet];
this._glassPaneShadow.appendChild(this._actionPointElement);
- const styleElement = document.createElement('style');
- styleElement.textContent = highlightCSS;
- this._glassPaneShadow.appendChild(styleElement);
}
install() {
diff --git a/packages/playwright-core/src/server/injected/recorder/recorder.ts b/packages/playwright-core/src/server/injected/recorder/recorder.ts
index 2074ffa67f..e4b886eb17 100644
--- a/packages/playwright-core/src/server/injected/recorder/recorder.ts
+++ b/packages/playwright-core/src/server/injected/recorder/recorder.ts
@@ -50,6 +50,20 @@ interface RecorderTool {
onScroll?(event: Event): void;
}
+const kIcons = ``;
+
class NoneTool implements RecorderTool {
cursor() {
return 'default';
@@ -769,7 +783,8 @@ class Overlay {
this._recorder = recorder;
const document = this._recorder.injectedScript.document;
this._overlayElement = document.createElement('x-pw-overlay');
-
+ const iconsSvgElement = new DOMParser().parseFromString(kIcons, 'image/svg+xml').documentElement;
+ this._overlayElement.appendChild(iconsSvgElement);
const toolsListElement = document.createElement('x-pw-tools-list');
this._overlayElement.appendChild(toolsListElement);
@@ -942,7 +957,7 @@ export class Recorder {
private _actionSelectorModel: HighlightModel | null = null;
readonly highlight: Highlight;
readonly overlay: Overlay | undefined;
- private _styleElement: HTMLStyleElement;
+ private _stylesheet: CSSStyleSheet;
state: UIState = { mode: 'none', testIdAttributeName: 'data-testid', language: 'javascript', overlay: { offsetX: 0 } };
readonly document: Document;
delegate: RecorderDelegate = {};
@@ -966,11 +981,11 @@ export class Recorder {
this.overlay = new Overlay(this);
this.overlay.setUIState(this.state);
}
- this._styleElement = this.document.createElement('style');
- this._styleElement.textContent = `
+ this._stylesheet = new CSSStyleSheet();
+ this._stylesheet.replaceSync(`
body[data-pw-cursor=pointer] *, body[data-pw-cursor=pointer] *::after { cursor: pointer !important; }
body[data-pw-cursor=text] *, body[data-pw-cursor=text] *::after { cursor: text !important; }
- `;
+ `);
this.installListeners();
if (injectedScript.isUnderTest)
@@ -999,7 +1014,7 @@ export class Recorder {
];
this.highlight.install();
this.overlay?.install();
- this.injectedScript.document.head.appendChild(this._styleElement);
+ this.document.adoptedStyleSheets = [...this.document.adoptedStyleSheets, this._stylesheet];
}
private _switchCurrentTool() {
diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts
index a54ae4d421..ee6e174f12 100644
--- a/tests/library/inspector/cli-codegen-1.spec.ts
+++ b/tests/library/inspector/cli-codegen-1.spec.ts
@@ -15,6 +15,7 @@
*/
import { test, expect } from './inspectorTest';
+import type { ConsoleMessage } from 'playwright';
test.describe('cli codegen', () => {
test.skip(({ mode }) => mode !== 'default');
@@ -841,4 +842,12 @@ await page.GetByRole(AriaRole.Button, new() { Name = "Submit" }).ClickAsync();`)
await page.goto(server.PREFIX + `/empty.html`);
await recorder.waitForOutput('JavaScript', `await page.goto('${server.PREFIX}/empty.html');`);
});
+
+ test('should not throw csp directive violation errors', async ({ page, openRecorder, server }) => {
+ await openRecorder();
+ await page.goto(server.PREFIX + '/csp.html');
+ const predicate = (msg: ConsoleMessage) => msg.type() === 'error' && /Content[\- ]Security[\- ]Policy/i.test(msg.text());
+ await expect(page.waitForEvent('console', { predicate, timeout: 1000 })).rejects.toThrow();
+ await page.pause();
+ });
});