#311 by GitHub stars

remorses/playwriter

Chrome extension & CLI to let agents control your browser. Runs Playwright snippets in a stateful sandbox. Available as CLI or MCP

History

Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.

View weekly changes

playwriter/src/SKILL.md

Week of Nov 2, 2026 · +0 / −0 lines

Before Network or broad shell → After Network or broad shell

bf2b96717e2b → 04342b0a8fc4

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Network or broad shell

First observation → bf2b96717e2b

No earlier version was observed for comparison.

Compare on GitHub

skills/playwriter/SKILL.md

Week of Nov 2, 2026 · +0 / −0 lines

Before Instructions only → After Network or broad shell

bf2b96717e2b → 04342b0a8fc4

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Instructions only

First observation → bf2b96717e2b

No earlier version was observed for comparison.

Compare on GitHub

View on GitHubAdd to my skills

Verified commit 04342b0a8fc42c95702687191425f7b3cd7dc13a

git clone --filter=blob:none --no-checkout https://github.com/remorses/playwriter.git .hotskills/remorses-playwriter && git -C .hotskills/remorses-playwriter checkout --detach 04342b0a8fc42c95702687191425f7b3cd7dc13a # Copy each selected skill directory from .hotskills/remorses-playwriter into .agents/skills/<skill-name>/
4.1kGitHub stars
16stars in 7 days
2skills in this repository
45commits in 30 days

Heat

5.6
  • Star growth, last 7 daysAhead of 66% of tracked repositories
  • Star growth, last 24 hoursAhead of 69% of tracked repositories
  • Rank movement, last 7 daysAhead of 40% of tracked repositories
  • Commits, last 30 daysAhead of 90% of tracked repositories
  • Accounts asking about it through MCP, last 7 daysNot available
  • Hot votes this weekAhead of 0% of tracked repositories

Heat never changes the order by stars, and sponsorship never touches it. How heat works

Stars over time

Aug 1, 2026Nov 6, 20264,063

Individual skills in this repository

How it works

When your agent uses it

What it loads into context

Frontmatter

0 tokens

Always available to the agent

SKILL.md

17,198 tokens

When the skill is activated

Reference documents

7,521 tokens

Loaded on request

Token counts are estimates. Scripts run separately; they are not counted as reference context.

The playbook

  1. CLI Usage
  2. context variables
  3. rules
  4. interaction feedback loop
  5. common mistakes to avoid
  6. accessibility snapshots
  7. choosing between snapshot methods
  8. selector best practices
  9. working with pages
  10. navigation
  11. common patterns
  12. utility functions
  13. pinned elements
  14. taking screenshots
  15. page.evaluate
  16. loading files
  17. network interception
  18. computer use (low-level mouse/keyboard)
  19. Ghost Browser integration

Scripts executed separately

  • a11y-client.ts
  • action-recorder.ts
  • action-recorder.unit.test.ts
  • aria-snapshot.test.ts
  • aria-snapshot.ts
  • aria-snapshot.unit.test.ts
  • assets/cursors/screen-studio/pointer-macos-tahoe-svg.ts
  • audio-tap-client.ts
  • browser-config.ts
  • browser-install.ts
  • browser-launch.ts
  • cdp-log.test.ts
  • cdp-log.ts
  • cdp-relay.ts
  • cdp-session.ts
  • cdp-types.ts
  • channel-owner-inspect.test.ts
  • chrome-discovery.test.ts
  • chrome-discovery.ts
  • clean-html.ts
  • cli-help.test.ts
  • cli.ts
  • cloud-client.ts
  • cloud-scope.test.ts
  • cloud-scope.ts
  • create-logger.ts
  • debugger-examples-types.ts
  • debugger-examples.ts
  • debugger.ts
  • diff-utils.test.ts
  • diff-utils.ts
  • editor-examples.ts
  • editor.ts
  • executor.ts
  • executor.unit.test.ts
  • extension-connection.test.ts
  • ffmpeg.ts
  • ghost-browser.ts
  • ghost-cursor-client.ts
  • ghost-cursor-controller.ts
  • ghost-cursor.ts
  • htmlrewrite.test.ts
  • htmlrewrite.ts
  • index.ts
  • kill-port.ts
  • kitty-graphics.test.ts
  • kitty-graphics.ts
  • locator-selector.test.ts
  • mcp-client.ts
  • mcp.ts
  • on-mouse-action.test.ts
  • package-paths.ts
  • page-markdown.ts
  • performance-examples.ts
  • playwright-import.ts
  • popup-relocation.test.ts
  • protocol.test.ts
  • protocol.ts
  • react-source.ts
  • recorder.test.ts
  • relay-client.ts
  • relay-core.test.ts
  • relay-navigation.test.ts
  • relay-session.test.ts
  • relay-state.test.ts
  • relay-state.ts
  • remote-control.ts
  • remote-control.unit.test.ts
  • scoped-fs.test.ts
  • scoped-fs.ts
  • screen-recording.test.ts
  • screen-recording.ts
  • screencast-background-tab.test.ts
  • snapshot-tools.test.ts
  • start-relay-server.ts
  • styles-examples.ts
  • styles.ts
  • tab-groups.test.ts
  • telemetry.ts
  • test-declarations.ts
  • test-utils.ts
  • utils.ts
  • wait-for-page-load.ts

Files

  • __snapshots__/x.com.processed.htmlasset47,086 bytes
  • __snapshots__/x.com.processed.withStyles.htmlasset223,485 bytes
  • a11y-client.tsruns7,951 bytes
  • action-recorder.tsruns56,161 bytes
  • action-recorder.unit.test.tsruns15,291 bytes
  • aria-snapshot.test.tsruns14,712 bytes
  • aria-snapshot.tsruns53,437 bytes
  • aria-snapshot.unit.test.tsruns17,214 bytes
  • assets/cursors/screen-studio/pointer-macos-tahoe-svg.tsruns2,017 bytes
  • assets/cursors/screen-studio/pointer-macos-tahoe.svgasset1,772 bytes
  • assets/x.com.htmlasset1,766,620 bytes
  • audio-tap-client.tsruns9,705 bytes
  • browser-config.tsruns5,724 bytes
  • browser-install.tsruns8,325 bytes
  • browser-launch.tsruns1,513 bytes
  • cdp-log.test.tsruns5,257 bytes
  • cdp-log.tsruns4,796 bytes
  • cdp-relay.tsruns123,121 bytes
  • cdp-session.tsruns2,851 bytes
  • cdp-types.tsruns3,848 bytes
  • channel-owner-inspect.test.tsruns3,807 bytes
  • chrome-discovery.test.tsruns1,428 bytes
  • chrome-discovery.tsruns6,990 bytes
  • clean-html.tsruns3,901 bytes
  • cli-help.test.tsruns3,134 bytes
  • cli.tsruns91,177 bytes
  • cloud-client.tsruns5,926 bytes
  • cloud-scope.test.tsruns3,682 bytes
  • cloud-scope.tsruns6,596 bytes
  • create-logger.tsruns2,129 bytes
  • debugger-examples-types.tsruns889 bytes
  • debugger-examples.tsruns1,961 bytes
  • debugger.tsruns21,415 bytes
  • diff-utils.test.tsruns5,254 bytes
  • diff-utils.tsruns2,433 bytes
  • editor-examples.tsruns4,060 bytes
  • editor.tsruns13,243 bytes
  • executor.tsruns80,694 bytes
  • executor.unit.test.tsruns6,868 bytes
  • extension-connection.test.tsruns50,138 bytes
  • ffmpeg.tsruns24,324 bytes
  • ghost-browser.tsruns4,952 bytes
  • ghost-cursor-client.tsruns14,906 bytes
  • ghost-cursor-controller.tsruns3,865 bytes
  • ghost-cursor.tsruns3,420 bytes
  • htmlrewrite.test.tsruns378,138 bytes
  • htmlrewrite.tsruns11,551 bytes
  • index.tsruns1,309 bytes
  • kill-port.tsruns6,083 bytes
  • kitty-graphics.test.tsruns5,116 bytes
  • kitty-graphics.tsruns2,622 bytes
  • locator-selector.test.tsruns4,879 bytes
  • mcp-client.tsruns1,976 bytes
  • mcp.tsruns13,396 bytes
  • on-mouse-action.test.tsruns8,877 bytes
  • package-paths.tsruns1,165 bytes
  • page-markdown.tsruns7,124 bytes
  • performance-examples.tsruns5,302 bytes
  • playwright-import.tsruns1,779 bytes
  • popup-relocation.test.tsruns13,509 bytes
  • protocol.test.tsruns9,419 bytes
  • protocol.tsruns13,088 bytes
  • react-source.tsruns10,910 bytes
  • recorder-prompt.mddoc19,263 bytes
  • recorder.test.tsruns28,380 bytes
  • relay-client.tsruns18,657 bytes
  • relay-core.test.tsruns68,456 bytes
  • relay-navigation.test.tsruns35,634 bytes
  • relay-session.test.tsruns47,736 bytes
  • relay-state.test.tsruns26,840 bytes
  • relay-state.tsruns19,719 bytes
  • remote-control.tsruns15,446 bytes
  • remote-control.unit.test.tsruns11,515 bytes
  • resource.mddoc11,550 bytes
  • scoped-fs.test.tsruns5,151 bytes
  • scoped-fs.tsruns15,500 bytes
  • screen-recording.test.tsruns14,554 bytes
  • screen-recording.tsruns48,637 bytes
  • screencast-background-tab.test.tsruns5,560 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • skill.mdcore72,577 bytes
  • snapshot-tools.test.tsruns36,201 bytes
  • snapshots/page-markdown-output.txtdoc291 bytes
  • start-relay-server.tsruns2,287 bytes
  • styles-examples.tsruns2,735 bytes
  • styles.tsruns9,522 bytes
  • tab-groups.test.tsruns17,856 bytes
  • telemetry.tsruns5,504 bytes
  • test-declarations.tsruns684 bytes
  • test-utils.tsruns11,926 bytes
  • utils.tsruns4,842 bytes
  • wait-for-page-load.tsruns4,912 bytes
Read SKILL.md
## CLI Usage

If `playwriter` command is not found, install globally or use npx/bunx:

```bash
npm install -g playwriter@latest
# or use without installing:
npx playwriter@latest session new --tab-group docs
bunx playwriter@latest session new --tab-group docs
```

If using npx or bunx always use @latest for the first session command. so we are sure of using the latest version of the package

### Session management
View the complete source on GitHub

Skills included

  • playwriter

Repository facts

License
MIT
Created
Nov 13, 2025
Last pushed
Nov 3, 2026
Forks
195
Open issues
18
Project activity
Active

Rank over the last 12 weeks

Now #311 · best #240 · down 37 in 30 days

  1. #303 on Oct 31
  2. #306 from Nov 1 to Nov 2
  3. #310 on Nov 3
  4. #309 on Nov 4
  5. #310 on Nov 5
  6. #311 since Nov 6
71 earlier periods
  1. #236 on Aug 1
  2. #234 from Aug 7 to Aug 8
  3. #232 on Aug 9
  4. #239 on Aug 10
  5. #235 on Aug 11
  6. #233 on Aug 12
  7. #237 on Aug 14
  8. #242 on Aug 16
  9. #241 on Aug 17
  10. #247 on Aug 18
  11. #245 on Aug 19
  12. #244 on Aug 20
  13. #243 on Aug 21
  14. #240 on Aug 22
  15. #246 from Aug 23 to Aug 25
  16. #245 on Aug 26
  17. #248 on Aug 27
  18. #247 on Aug 29
  19. #248 on Aug 30
  20. #250 on Aug 31
  21. #255 on Sep 1
  22. #252 on Sep 2
  23. #260 on Sep 3
  24. #253 on Sep 4
  25. #255 on Sep 5
  26. #252 on Sep 6
  27. #257 on Sep 7
  28. #255 from Sep 8 to Sep 9
  29. #256 on Sep 10
  30. #255 on Sep 11
  31. #256 on Sep 12
  32. #260 on Sep 13
  33. #261 from Sep 14 to Sep 15
  34. #260 on Sep 16
  35. #259 on Sep 17
  36. #262 on Sep 18
  37. #264 on Sep 20
  38. #267 on Sep 21
  39. #265 on Sep 22
  40. #266 on Sep 23
  41. #267 on Sep 24
  42. #262 on Sep 25
  43. #264 on Sep 27
  44. #269 on Sep 28
  45. #270 on Sep 29
  46. #266 on Sep 30
  47. #267 on Oct 1
  48. #272 on Oct 2
  49. #266 on Oct 3
  50. #264 on Oct 4
  51. #270 on Oct 5
  52. #271 on Oct 6
  53. #274 on Oct 7
  54. #275 on Oct 8
  55. #279 on Oct 9
  56. #275 on Oct 10
  57. #277 on Oct 11
  58. #280 on Oct 12
  59. #279 on Oct 14
  60. #282 on Oct 15
  61. #280 on Oct 16
  62. #281 on Oct 17
  63. #282 from Oct 18 to Oct 19
  64. #284 on Oct 20
  65. #289 on Oct 21
  66. #287 on Oct 23
  67. #291 on Oct 24
  68. #295 on Oct 25
  69. #299 on Oct 28
  70. #300 on Oct 29
  71. #302 on Oct 30

Before you install

Network or broad shell

Automated signals, not a guarantee

Checked Nov 6, 2026

Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.

Show 37 notes
  • playwriter/src/assets/x.com.html:1 Analysis incomplete: file exceeds text byte budget
  • playwriter/src/assets/x.com.html:11441 Analysis incomplete: regex work limit reached
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • playwriter/src/skill.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
Show all 1,386 signals by file

playwriter/src/a11y-client.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 89
    const svg = doc.createElementNS('http://www.w3.org/2000/svg', 'svg')
  • Network accessline 95
    const defs = doc.createElementNS('http://www.w3.org/2000/svg', 'defs')
  • Network accessline 102
    }     const markerId = `arrow-${color.replace('#', '')}`     const marker = doc.createElementNS('http://www.w3.org/2000/svg', 'marker')
  • Network accessline 103
    const markerId = `arrow-${color.replace('#', '')}     const marker = doc.createElementNS('http://www.w3.org/2000/svg', 'marker')
  • Network accessline 104
    const marker = doc.createElementNS('http://www.w3.org/2000/svg', 'marker')
  • Network accessline 110
    marker.setAttribute('markerHeight', '6')     marker.setAttribute('orient', 'auto-start-reverse')     const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path')
  • Network accessline 111
    marker.setAttribute('orient', 'auto-start-reverse')     const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path')     path.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z')
  • Network accessline 112
    const path = doc.createElementNS('http://www.w3.org/2000/svg', 'path')
  • Network accessline 191
    const line = doc.createElementNS('http://www.w3.org/2000/svg', 'line')

playwriter/src/action-recorder.ts

  • Executable scriptline 1
    Executable file

playwriter/src/action-recorder.unit.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 55
    describe('isTelemetryUrl', () => {   test('drops analytics collectors and keeps site APIs', () => {     expect(isTelemetryUrl('https://www.google-analytics.com/j/collect?v=1')).toBe(true)
  • Network accessline 56
    test('drops analytics collectors and keeps site APIs', () => {     expect(isTelemetryUrl('https://www.google-analytics.com/j/collect?v=1')).toBe(true)     expect(isTelemetryUrl('https://region1.google-analytics.com/g/collect?v=2')).toBe(tru
  • Network accessline 57
    expect(isTelemetryUrl('https://www.google-analytics.com/j/collect?v=1')).toBe(true)
  • Network accessline 58
    expect(isTelemetryUrl('https://region1.google-analytics.com/g/collect?v=2')).toBe(true)
  • Network accessline 59
    expect(isTelemetryUrl('https://uj5wyc0l7x-dsn.algolia.net/1/indexes/Item_dev/query')).toBe(false)
  • Network accessline 60
    expect(isTelemetryUrl('https://news.ycombinator.com/x')).toBe(false)
  • Network accessline 61
    expect(isTelemetryUrl('https://api.twitter.com/2/tweets')).toBe(false)
  • Network accessline 62
    expect(isTelemetryUrl('https://example.com/api?next=https://analytics.example')).toBe(false)
  • Network accessline 383
    expect(       formatAmbiguousRecordingsError([         { recordingId: '3', sessionId: '1', pageUrls: ['https://app.example.com/settings'], lastUrl: '' },
  • Network accessline 384
    formatAmbiguousRecordingsError([         { recordingId: '3', sessionId: '1', pageUrls: ['https://app.example.com/settings'], lastUrl: '' },         { recordingId: '5', sessionId: '2', pageUrls: [], lastUrl: 'https://github.com/remorses/play
  • Network accessline 385
    { recordingId: '3', sessionId: '1', pageUrls: ['https://app.example.com/settings'], lastUrl: '' },
  • Network accessline 386
    { recordingId: '5', sessionId: '2', pageUrls: [], lastUrl: 'https://github.com/remorses/playwriter' },
  • Network accessline 391
    3  session 1  https://app.example.com/settings
  • Network accessline 392
    5  session 2  https://github.com/remorses/playwriter"
  • Network accessline 413
    const events = [       { id: 1, t: 0, ms: 0, type: 'action', code: 'click' },       { id: 2, t: 0.1, ms: 100, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },
  • Network accessline 414
    { id: 1, t: 0, ms: 0, type: 'action', code: 'click' },       { id: 2, t: 0.1, ms: 100, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },       { id: 3, t: 0.1, ms: 110, type: 'network', method: 'POST', url: 'https:/
  • Network accessline 415
    { id: 2, t: 0.1, ms: 100, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },
  • Network accessline 416
    { id: 3, t: 0.1, ms: 110, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },
  • Network accessline 417
    { id: 4, t: 0.1, ms: 120, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },
  • Network accessline 418
    { id: 5, t: 0.2, ms: 200, type: 'network', method: 'POST', url: 'https://a.com/generate', status: 403 },
  • Network accessline 419
    { id: 6, t: 0.3, ms: 300, type: 'toast', role: 'status', text: 'Concurrent limit reached' },       { id: 7, t: 0.4, ms: 400, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },     ]
  • Network accessline 420
    { id: 7, t: 0.4, ms: 400, type: 'network', method: 'POST', url: 'https://a.com/list', status: 200 },

playwriter/src/aria-snapshot.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 53
    return {     baseUrl: `http://127.0.0.1:${address.port}`,
  • Network accessline 54
    baseUrl: `http://127.0.0.1:${address.port}`,     close: () => {       for (const socket of openSockets) {
  • Network accessline 96
    const sites = [     { name: 'hackernews', url: 'https://news.ycombinator.com' },
  • Network accessline 97
    { name: 'hackernews', url: 'https://news.ycombinator.com' },
  • Network accessline 98
    { name: 'github', url: 'https://github.com' },
  • Network accessline 99
    { name: 'prosemirror', url: 'https://prosemirror.net/' },
  • Network accessline 144
    it('prosemirror editor - contenteditable appears in snapshot and is interactable', async () => {     await page.goto('https://prosemirror.net/', { waitUntil: 'domcontentloaded' })
  • Network accessline 145
    await page.goto('https://prosemirror.net/', { waitUntil: 'domcontentloaded' })

playwriter/src/aria-snapshot.ts

  • Executable scriptline 1
    Executable file

playwriter/src/aria-snapshot.unit.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/assets/cursors/screen-studio/pointer-macos-tahoe-svg.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 5
    export const SCREENSTUDIO_POINTER_MACOS_TAHOE_SVG = "<svg width=\"618\" height=\"958\" viewBox=\"0 0 618 958\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g filter=\"url(#filter0_d_384_27)\">\n<path fill-rule=\"evenodd\" clip-rule
  • Possible obfuscationline 5
    export const SCREENSTUDIO_POINTER_MACOS_TAHOE_SVG = "<svg width=\"618\" height=\"958\" viewBox=\"0 0 618 958\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<g filter=\"url(#filter0_d_384_27)\">\n<path fill-rule=\"evenodd\" clip-rule

playwriter/src/assets/cursors/screen-studio/pointer-macos-tahoe.svg

  • Network accessline 1
    <svg width="618" height="958" viewBox="0 0 618 958" fill="none" xmlns="http://www.w3.org/2000/svg">

playwriter/src/assets/x.com.html

  • Network accessline 167
    @font-face {         font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Light.a929468a.woff2) format('woff2');
  • Network accessline 168
    font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Light.a929468a.woff2) format('woff2');         font-weight: 300;
  • Network accessline 169
    src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Light.a929468a.woff2) format('woff2');
  • Network accessline 174
    @font-face {         font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Regular.58c84f6a.woff2) format('woff2');
  • Network accessline 175
    font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Regular.58c84f6a.woff2) format('woff2');         font-weight: 400;
  • Network accessline 176
    src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Regular.58c84f6a.woff2) format('woff2');
  • Network accessline 181
    @font-face {         font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Medium.bc7d8f1a.woff2) format('woff2');
  • Network accessline 182
    font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Medium.bc7d8f1a.woff2) format('woff2');         font-weight: 500;
  • Network accessline 183
    src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Medium.bc7d8f1a.woff2) format('woff2');
  • Network accessline 188
    @font-face {         font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Bold.0d6a47ca.woff2) format('woff2');
  • Network accessline 189
    font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Bold.0d6a47ca.woff2) format('woff2');         font-weight: 700;
  • Network accessline 190
    src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-Bold.0d6a47ca.woff2) format('woff2');
  • Network accessline 195
    @font-face {         font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-ExtraBold.b130af7a.woff2) format('woff2');
  • Network accessline 196
    font-family: Vazirmatn;         src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-ExtraBold.b130af7a.woff2) format('woff2');         font-weight: 800;
  • Network accessline 197
    src: url(https://abs.twimg.com/responsive-web/client-web/Vazirmatn-ExtraBold.b130af7a.woff2) format('woff2');
  • Network accessline 205
    font-family: TwitterChirp;         src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.3a18e64a.woff2) format('woff2'),
  • Network accessline 206
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.3a18e64a.woff2) format('woff2'),           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.7a5673aa.woff) format('woff');
  • Network accessline 207
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.3a18e64a.woff2) format('woff2'),
  • Network accessline 208
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.7a5673aa.woff) format('woff');
  • Network accessline 214
    font-family: TwitterChirp;         src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.80fda27a.woff2) format('woff2'),
  • Network accessline 215
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.80fda27a.woff2) format('woff2'),           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.60b215ba.woff) format('woff');
  • Network accessline 216
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.80fda27a.woff2) format('woff2'),
  • Network accessline 217
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.60b215ba.woff) format('woff');
  • Network accessline 223
    font-family: TwitterChirp;         src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.f8e2739a.woff2) format('woff2'),
  • Network accessline 224
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.f8e2739a.woff2) format('woff2'),           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.20fc288a.woff) format('woff');
  • Network accessline 225
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.f8e2739a.woff2) format('woff2'),
  • Network accessline 226
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.20fc288a.woff) format('woff');
  • Network accessline 232
    font-family: TwitterChirp;         src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.ebb56aba.woff2) format('woff2'),
  • Network accessline 233
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.ebb56aba.woff2) format('woff2'),           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.a573679a.woff) format('woff');
  • Network accessline 234
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.ebb56aba.woff2) format('woff2'),
  • Network accessline 235
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.a573679a.woff) format('woff');
  • Network accessline 241
    font-family: TwitterChirp;         src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.f44ae4ea.woff2) format('woff2'),
  • Network accessline 242
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.f44ae4ea.woff2) format('woff2'),           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.d70ec7ca.woff) format('woff');
  • Network accessline 243
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.f44ae4ea.woff2) format('woff2'),
  • Network accessline 244
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.d70ec7ca.woff) format('woff');
  • Network accessline 250
    font-family: TwitterChirpExtendedHeavy;         src:           url(https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff2) format('woff2'),
  • Network accessline 251
    src:           url(https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff2) format('woff2'),           url(https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff) format('woff');
  • Network accessline 252
    url(https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff2) format('woff2'),
  • Network accessline 253
    url(https://abs.twimg.com/fonts/v1/chirp-extended-heavy-web.woff) format('woff');
  • Network accessline 279
    as="script"       crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/vendor.a575caea.js"
  • Network accessline 280
    crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/vendor.a575caea.js"     />
  • Network accessline 281
    href="https://abs.twimg.com/responsive-web/client-web/vendor.a575caea.js"
  • Network accessline 286
    as="script"       crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/i18n/it.cc7e6ffa.js"
  • Network accessline 287
    crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/i18n/it.cc7e6ffa.js"     />
  • Network accessline 288
    href="https://abs.twimg.com/responsive-web/client-web/i18n/it.cc7e6ffa.js"
  • Network accessline 293
    as="script"       crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/main.dba2a2aa.js"
  • Network accessline 294
    crossorigin="anonymous"       href="https://abs.twimg.com/responsive-web/client-web/main.dba2a2aa.js"     />
  • Network accessline 295
    href="https://abs.twimg.com/responsive-web/client-web/main.dba2a2aa.js"
  • Network accessline 297
    <meta       http-equiv="onion-location"       content="https://twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/"
  • Network accessline 298
    http-equiv="onion-location"       content="https://twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/"     />
  • Network accessline 299
    content="https://twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion/"
  • Network accessline 308
    rel="apple-touch-icon"       sizes="192x192"       href="https://abs.twimg.com/responsive-web/client-web/icon-ios.77d25eba.png"
  • Network accessline 309
    sizes="192x192"       href="https://abs.twimg.com/responsive-web/client-web/icon-ios.77d25eba.png"     />
  • Network accessline 310
    href="https://abs.twimg.com/responsive-web/client-web/icon-ios.77d25eba.png"
  • Network accessline 317
    rel="mask-icon"       sizes="any"       href="https://abs.twimg.com/responsive-web/client-web/icon-svg.ea5ff4aa.svg"
  • Network accessline 318
    sizes="any"       href="https://abs.twimg.com/responsive-web/client-web/icon-svg.ea5ff4aa.svg"       color="#1D9BF0"
  • Network accessline 319
    href="https://abs.twimg.com/responsive-web/client-web/icon-svg.ea5ff4aa.svg"
  • Network accessline 1308
    </style>     <title>Home / X</title>     <meta content="https://abs.twimg.com/rweb/ssr/default/v2/og/image.png" property="og:image" data-rh="true" />
  • Network accessline 1309
    <title>Home / X</title>     <meta content="https://abs.twimg.com/rweb/ssr/default/v2/og/image.png" property="og:image" data-rh="true" />     <style type="text/css">
  • Network accessline 1310
    <meta content="https://abs.twimg.com/rweb/ssr/default/v2/og/image.png" property="og:image" data-rh="true" />
  • Network accessline 1371
    /*   1. Add the correct height in Firefox.   2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
  • Network accessline 1372
    1. Add the correct height in Firefox.   2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)   3. Ensure horizontal rules are visible by default.
  • Network accessline 1373
    2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
  • Network accessline 1474
    /*   1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
  • Network accessline 1475
    1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
  • Network accessline 1476
    2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
  • Network accessline 1556
    /*   Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
  • Network accessline 1557
    Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
  • Network accessline 1706
    /*   1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
  • Network accessline 1707
    1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
  • Network accessline 1743
    /*   1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 1744
    1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 1745
    2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
  • Network accessline 1763
    /*   Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 1764
    Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 3185
    /* https://v3.tailwindcss.com/docs/drop-shadow */
  • Network accessline 3262
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.3a18e64a.woff2) format('woff2'),
  • Network accessline 3263
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.3a18e64a.woff2) format('woff2'),
  • Network accessline 3264
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Light.7a5673aa.woff) format('woff');
  • Network accessline 3276
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.80fda27a.woff2) format('woff2'),
  • Network accessline 3277
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.80fda27a.woff2) format('woff2'),
  • Network accessline 3278
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Regular.60b215ba.woff) format('woff');
  • Network accessline 3290
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.f8e2739a.woff2) format('woff2'),
  • Network accessline 3291
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.f8e2739a.woff2) format('woff2'),
  • Network accessline 3292
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Medium.20fc288a.woff) format('woff');
  • Network accessline 3304
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.ebb56aba.woff2) format('woff2'),
  • Network accessline 3305
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.ebb56aba.woff2) format('woff2'),
  • Network accessline 3306
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Bold.a573679a.woff) format('woff');
  • Network accessline 3318
    src:           url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.f44ae4ea.woff2) format('woff2'),
  • Network accessline 3319
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.f44ae4ea.woff2) format('woff2'),
  • Network accessline 3320
    url(https://abs.twimg.com/responsive-web/client-web/Chirp-Heavy.d70ec7ca.woff) format('woff');
  • Network accessline 3538
    <style type="text/css"></style>     <meta content="website" property="og:type" data-rh="true" />     <meta content="https://x.com/i/grok" property="og:url" data-rh="true" />
  • Network accessline 3539
    <meta content="website" property="og:type" data-rh="true" />     <meta content="https://x.com/i/grok" property="og:url" data-rh="true" />     <meta
  • Network accessline 3540
    <meta content="https://x.com/i/grok" property="og:url" data-rh="true" />
  • Network accessline 4435
    /* ! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com
  • Network accessline 4436
    ! tailwindcss v3.4.17 | MIT License | https://tailwindcss.com
  • Network accessline 4439
    /* 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
  • Network accessline 4440
    1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
  • Network accessline 4441
    2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
  • Network accessline 4507
    /* 1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
  • Network accessline 4508
    1. Add the correct height in Firefox. 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 3. Ensure horizontal rules are visible by default.
  • Network accessline 4509
    2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
  • Network accessline 4612
    /* 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
  • Network accessline 4613
    1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
  • Network accessline 4614
    2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
  • Network accessline 4694
    /* Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
  • Network accessline 4695
    Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
  • Network accessline 4812
    /* 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
  • Network accessline 4813
    1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
  • Network accessline 4850
    /* 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 4851
    1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 4852
    2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
  • Network accessline 4870
    /* Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
  • Network accessline 4871
    Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)

playwriter/src/audio-tap-client.ts

  • Executable scriptline 1
    Executable file

playwriter/src/browser-config.ts

  • Executable scriptline 1
    Executable file

playwriter/src/browser-install.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 14
    const LAST_KNOWN_GOOD_URL =   'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json'
  • Network accessline 15
    'https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json'
  • Network accessline 122
    async function fetchDownloadUrl(): Promise<VersionInfo> {   const response = await fetch(LAST_KNOWN_GOOD_URL, {
  • Network accessline 123
    const response = await fetch(LAST_KNOWN_GOOD_URL, {
  • Network accessline 184
    async function downloadFileAttempt(url: string, destPath: string): Promise<void> {   const response = await fetch(url, {
  • Network accessline 185
    const response = await fetch(url, {

playwriter/src/browser-launch.ts

  • Executable scriptline 1
    Executable file

playwriter/src/cdp-log.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 146
    method: 'Page.navigate',         params: {           url: `https://playwriter.dev/remote-control#${secret}`,
  • Network accessline 147
    params: {           url: `https://playwriter.dev/remote-control#${secret}`,           tunnel: `wss://${secret}-tunnel.playwriter.dev/extension`,
  • Network accessline 148
    url: `https://playwriter.dev/remote-control#${secret}`,
  • Network accessline 170
    await logger.log({       viewer: `https://playwriter.dev/remote-control#${secret}`,
  • Network accessline 171
    viewer: `https://playwriter.dev/remote-control#${secret}`,

playwriter/src/cdp-log.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 76
    // Batch buffer: accumulate lines and flush periodically to reduce disk I/O.   // Without batching, high-frequency CDP events cause thousands of appendFile   // calls per second. See: https://github.com/remorses/playwriter/issues/96
  • Network accessline 78
    // calls per second. See: https://github.com/remorses/playwriter/issues/96

playwriter/src/cdp-relay.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 76
    // CDP events dropped entirely (not forwarded to Playwright clients, not logged). // Only events that no Playwright API depends on. See: https://github.com/remorses/playwriter/issues/96
  • Network accessline 77
    // Only events that no Playwright API depends on. See: https://github.com/remorses/playwriter/issues/96
  • Network accessline 928
    // Host header validation to prevent DNS rebinding attacks.   // DNS rebinding is worse than a simple cross-origin request: the attacker   // serves a page from http://evil.com:19988, then rebinds the DNS to
  • Network accessline 929
    // DNS rebinding is worse than a simple cross-origin request: the attacker   // serves a page from http://evil.com:19988, then rebinds the DNS to   // 127.0.0.1. The browser now considers requests to our relay as same-origin,
  • Network accessline 930
    // serves a page from http://evil.com:19988, then rebinds the DNS to
  • Network accessline 985
    const authHeader = c.req.header('authorization') || ''     const bearerToken = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : null     const queryToken = new URL(c.req.url, 'http://localhost').searchParams.get('token')
  • Network accessline 986
    const bearerToken = authHeader.startsWith('Bearer ') ? authHeader.slice(7) : null     const queryToken = new URL(c.req.url, 'http://localhost').searchParams.get('token')     return bearerToken === token || queryToken === token
  • Network accessline 987
    const queryToken = new URL(c.req.url, 'http://localhost').searchParams.get('token')
  • Network accessline 1011
    // Missing Host header from non-browser clients (curl without Host) is fine
  • Network accessline 1071
    // CDP Discovery Endpoints - Standard Chrome DevTools Protocol HTTP API   // Allows tools like Playwright to discover the WebSocket URL via http://host:port
  • Network accessline 1072
    // Allows tools like Playwright to discover the WebSocket URL via http://host:port
  • Network accessline 1073
    // Spec: https://chromium.googlesource.com/chromium/src/+/main/content/browser/devtools/devtools_http_handler.cc
  • Network accessline 1174
    if (token) {         const url = new URL(c.req.url, 'http://localhost')
  • Network accessline 1175
    const url = new URL(c.req.url, 'http://localhost')
  • Network accessline 1183
    upgradeWebSocket((c) => {       const clientId = c.req.param('clientId') || 'default'       const url = new URL(c.req.url, 'http://localhost')
  • Network accessline 1184
    const clientId = c.req.param('clientId') || 'default'       const url = new URL(c.req.url, 'http://localhost')       const requestedExtensionId = url.searchParams.get('extensionId')
  • Network accessline 1185
    const url = new URL(c.req.url, 'http://localhost')
  • Network accessline 3014
    function disconnectCloudVm(tracking: CloudSessionTracking): void {     fetch(new URL('/api/cloud/disconnect', tracking.cloudBaseUrl).toString(), {
  • Network accessline 3015
    fetch(new URL('/api/cloud/disconnect', tracking.cloudBaseUrl).toString(), {

playwriter/src/cdp-session.ts

  • Executable scriptline 1
    Executable file

playwriter/src/cdp-types.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 100
    type: 'page',         title: 'Example',         url: 'https://example.com',
  • Network accessline 101
    title: 'Example',         url: 'https://example.com',         attached: true,
  • Network accessline 102
    url: 'https://example.com',
  • Network accessline 122
    method: 'Page.navigate',     params: {       url: 'https://example.com',
  • Network accessline 123
    params: {       url: 'https://example.com',     },
  • Network accessline 124
    url: 'https://example.com',
  • Network accessline 139
    requestId: 'req-1',       loaderId: 'loader-1',       documentURL: 'https://example.com',
  • Network accessline 140
    loaderId: 'loader-1',       documentURL: 'https://example.com',       request: {
  • Network accessline 141
    documentURL: 'https://example.com',
  • Network accessline 142
    request: {         url: 'https://example.com/api',         method: 'GET',
  • Network accessline 143
    url: 'https://example.com/api',

playwriter/src/channel-owner-inspect.test.ts

  • Network accessline 1
    /**  * Regression test for https://github.com/remorses/playwriter/issues/82
  • Executable scriptline 1
    Executable file
  • Network accessline 2
    * Regression test for https://github.com/remorses/playwriter/issues/82
  • Network accessline 3
    *  * User reported that running:  *   playwriter -s 1 -e 'await page.goto("https://example.com")'
  • Network accessline 4
    * User reported that running:  *   playwriter -s 1 -e 'await page.goto("https://example.com")'  * printed "all env vars" to the terminal.
  • Network accessline 5
    *   playwriter -s 1 -e 'await page.goto("https://example.com")'
  • Access to secretsline 31
    [Credential-related source omitted]
  • Network accessline 45
    const directInspect = util.inspect(proxy, { depth: 4 })     const nestedInspect = util.inspect(       { request: proxy, url: 'https://example.com' },
  • Network accessline 46
    const nestedInspect = util.inspect(       { request: proxy, url: 'https://example.com' },       { depth: 4 },
  • Network accessline 47
    { request: proxy, url: 'https://example.com' },
  • Network accessline 56
    expect(directInspect).toMatchInlineSnapshot(`"Channel<Response@test-guid>"`)     expect(nestedInspect).toMatchInlineSnapshot(`"{ request: Channel<Response@test-guid>, url: 'https://example.com' }"`)
  • Network accessline 57
    expect(nestedInspect).toMatchInlineSnapshot(`"{ request: Channel<Response@test-guid>, url: 'https://example.com' }"`)
  • Network accessline 70
    _connection: { _platform: { env: { LEAKED: SECRET_VALUE } } },       _initializer: {         url: 'https://example.com/',
  • Network accessline 71
    _initializer: {         url: 'https://example.com/',         status: 200,
  • Network accessline 72
    url: 'https://example.com/',
  • Network accessline 89
    expect(output).not.toContain(SECRET_VALUE)     expect(output).toMatchInlineSnapshot(       `"Response@response@abc123 { url: 'https://example.com/', status: 200, statusText: 'OK' }"`,
  • Network accessline 90
    expect(output).toMatchInlineSnapshot(       `"Response@response@abc123 { url: 'https://example.com/', status: 200, statusText: 'OK' }"`,     )
  • Network accessline 91
    `"Response@response@abc123 { url: 'https://example.com/', status: 200, statusText: 'OK' }"`,

playwriter/src/chrome-discovery.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/chrome-discovery.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 73
    async function probePortStatus(port: number, hostname = '127.0.0.1'): Promise<PortProbeStatus> {   try {     const response = await fetch(`http://${hostname}:${port}/json/version`, {
  • Network accessline 74
    try {     const response = await fetch(`http://${hostname}:${port}/json/version`, {       signal: AbortSignal.timeout(1000),
  • Network accessline 75
    const response = await fetch(`http://${hostname}:${port}/json/version`, {

playwriter/src/clean-html.ts

  • Executable scriptline 1
    Executable file

playwriter/src/cli-help.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 71
    await execFileAsync(         viteNodeBinary,         ['src/cli.ts', 'session', 'new', '--host', `http://127.0.0.1:${port}`],
  • Network accessline 72
    viteNodeBinary,         ['src/cli.ts', 'session', 'new', '--host', `http://127.0.0.1:${port}`],         {
  • Network accessline 73
    ['src/cli.ts', 'session', 'new', '--host', `http://127.0.0.1:${port}`],
  • Access to secretsline 80
    [Credential-related source omitted]

playwriter/src/cli.ts

  • Executable scriptline 1
    #!/usr/bin/env node
  • Network accessline 124
    .option('--token <token>', 'Authentication token (or use PLAYWRITER_TOKEN env var)')   .option('-s, --session <name>', 'Session ID (required for -e, get one with `playwriter session new`)')   .option('-e, --eval <code>', 'Execute JavaScript
  • Network accessline 125
    .option('-s, --session <name>', 'Session ID (required for -e, get one with `playwriter session new`)')   .option('-e, --eval <code>', 'Execute JavaScript code and exit, read https://playwriter.dev/SKILL.md for usage')   .option('-f, --file 
  • Network accessline 126
    .option('-e, --eval <code>', 'Execute JavaScript code and exit, read https://playwriter.dev/SKILL.md for usage')
  • Access to secretsline 193
    [Credential-related source omitted]
  • Network accessline 202
    const serverUrl = await getServerUrl(host)     const headers = buildAuthHeaders({ token })     const response = await fetch(`${serverUrl}/extensions/status`, {
  • Network accessline 203
    const headers = buildAuthHeaders({ token })     const response = await fetch(`${serverUrl}/extensions/status`, {       signal: AbortSignal.timeout(2000),
  • Network accessline 204
    const response = await fetch(`${serverUrl}/extensions/status`, {
  • Network accessline 207
    })     if (!response.ok) {       const fallback = await fetch(`${serverUrl}/extension/status`, {
  • Network accessline 208
    if (!response.ok) {       const fallback = await fetch(`${serverUrl}/extension/status`, {         signal: AbortSignal.timeout(2000),
  • Network accessline 209
    const fallback = await fetch(`${serverUrl}/extension/status`, {
  • Network accessline 446
    const serverUrl = await getServerUrl(options.host)       try {         const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 447
    try {         const response = await fetch(`${serverUrl}/cli/session/new`, {           method: 'POST',
  • Network accessline 448
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 492
    await ensureRelayForSessionCreation(isLocal)         const serverUrl = await getServerUrl(options.host)         const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 493
    const serverUrl = await getServerUrl(options.host)         const response = await fetch(`${serverUrl}/cli/session/new`, {           method: 'POST',
  • Network accessline 494
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 712
    : selectedExtension.stableKey || selectedExtension.extensionId         const cwd = process.cwd()         const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 713
    const cwd = process.cwd()         const response = await fetch(`${serverUrl}/cli/session/new`, {           method: 'POST',
  • Network accessline 714
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 807
    } else {           const cwd = process.cwd()           const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 808
    const cwd = process.cwd()           const response = await fetch(`${serverUrl}/cli/session/new`, {             method: 'POST',
  • Network accessline 809
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 872
    }): Promise<{ id: string; warning?: string | null }> {   const cwd = process.cwd()   const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 873
    const cwd = process.cwd()   const response = await fetch(`${serverUrl}/cli/session/new`, {     method: 'POST',
  • Network accessline 874
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Access to secretsline 964
    [Credential-related source omitted]
  • Access to secretsline 983
    [Credential-related source omitted]
  • Access to secretsline 1010
    [Credential-related source omitted]
  • Network accessline 1105
    let response: Response   try {     response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 1106
    try {     response = await fetch(`${serverUrl}/cli/session/new`, {       method: 'POST',
  • Network accessline 1107
    response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 1169
    const response = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 1243
    try {       const response = await fetch(`${serverUrl}/cli/sessions`, {
  • Network accessline 1244
    const response = await fetch(`${serverUrl}/cli/sessions`, {
  • Network accessline 1334
    try {       const response = await fetch(`${serverUrl}/cli/session/delete`, {
  • Network accessline 1335
    const response = await fetch(`${serverUrl}/cli/session/delete`, {
  • Network accessline 1383
    try {       const response = await fetch(`${serverUrl}/cli/session/update`, {
  • Network accessline 1384
    const response = await fetch(`${serverUrl}/cli/session/update`, {
  • Network accessline 1444
    try {       const response = await fetch(`${serverUrl}/cli/reset`, {
  • Network accessline 1445
    const response = await fetch(`${serverUrl}/cli/reset`, {
  • Network accessline 1607
    return explicit         }         const listResponse = await fetch(`${serverUrl}/cli/sessions`, {
  • Network accessline 1608
    [Credential-related source omitted]
  • Network accessline 1609
    const listResponse = await fetch(`${serverUrl}/cli/sessions`, {
  • Network accessline 1622
    const newResponse = await fetch(`${serverUrl}/cli/session/new`, {
  • Network accessline 1636
    const response = await fetch(`${serverUrl}/recorder/start`, {
  • Network accessline 1665
    const serverUrl = await getServerUrl(options.host)     try {       const response = await fetch(`${serverUrl}/recorder/stop`, {
  • Network accessline 1666
    try {       const response = await fetch(`${serverUrl}/recorder/stop`, {         method: 'POST',
  • Network accessline 1667
    const response = await fetch(`${serverUrl}/recorder/stop`, {
  • Network accessline 1685
    console.log('Next steps (full instructions were printed by `recorder start`):')       console.log('  1. playwriter skill')       console.log('     or https://playwriter.dev/SKILL.md')
  • Network accessline 1686
    console.log('  1. playwriter skill')       console.log('     or https://playwriter.dev/SKILL.md')       console.log(`  2. playwriter recorder events -r ${result.recordingId}`)
  • Network accessline 1687
    console.log('     or https://playwriter.dev/SKILL.md')
  • Network accessline 1688
    console.log(`  2. playwriter recorder events -r ${result.recordingId}`)       console.log('  3. Write SKILL.md + a named helper (submit.js, sdk.js) with playwriter -e examples from the events')       console.log('     or a standalone typed 
  • Network accessline 1689
    console.log('  3. Write SKILL.md + a named helper (submit.js, sdk.js) with playwriter -e examples from the events')       console.log('     or a standalone typed sdk.ts via connectViaExtension: https://playwriter.dev/docs/sessions#node-api'
  • Network accessline 1690
    console.log('     or a standalone typed sdk.ts via connectViaExtension: https://playwriter.dev/docs/sessions#node-api')
  • Network accessline 1721
    try {           const serverUrl = await getServerUrl(options.host)           const response = await fetch(`${serverUrl}/recorder/status`, {
  • Network accessline 1722
    [Credential-related source omitted]
  • Network accessline 1723
    const response = await fetch(`${serverUrl}/recorder/status`, {
  • Network accessline 1756
    }       const serverUrl = await getServerUrl(options.host)       const response = await fetch(`${serverUrl}/recorder/events/${recordingId ?? 'latest'}`, {
  • Network accessline 1757
    [Credential-related source omitted]
  • Network accessline 1758
    const response = await fetch(`${serverUrl}/recorder/events/${recordingId ?? 'latest'}`, {
  • Network accessline 1860
    const serverUrl = await getServerUrl(options.host)     try {       const response = await fetch(`${serverUrl}/recorder/status`, {
  • Network accessline 1861
    [Credential-related source omitted]
  • Network accessline 1862
    const response = await fetch(`${serverUrl}/recorder/status`, {
  • Access to secretsline 1903
    [Credential-related source omitted]
  • Access to secretsline 1916
    [Credential-related source omitted]
  • Network accessline 1980
    [Credential-related source omitted]
  • Network accessline 1981
    [Credential-related source omitted]
  • Network accessline 1982
    [Credential-related source omitted]
  • Network accessline 2083
    cli   .command('cloud login', 'Authenticate with playwriter.dev to use cloud browsers')   .option('--base-url <url>', 'Website base URL (default: https://playwriter.dev)')
  • Network accessline 2084
    .command('cloud login', 'Authenticate with playwriter.dev to use cloud browsers')   .option('--base-url <url>', 'Website base URL (default: https://playwriter.dev)')   .action(async (options, ctx) => {
  • Network accessline 2085
    .option('--base-url <url>', 'Website base URL (default: https://playwriter.dev)')
  • Network accessline 2087
    const baseUrl = options.baseUrl || ctx.process.env.PLAYWRITER_CLOUD_URL || 'https://playwriter.dev'
  • Access to secretsline 2113
    [Credential-related source omitted]
  • Access to secretsline 2114
    [Credential-related source omitted]

playwriter/src/cloud-client.ts

  • Executable scriptline 1
    Executable file
  • Access to secretsline 3
    [Credential-related source omitted]
  • Network accessline 11
    const DEFAULT_BASE_URL = 'https://playwriter.dev'
  • Access to secretsline 36
    [Credential-related source omitted]
  • Access to secretsline 41
    [Credential-related source omitted]
  • Network accessline 112
    const response = await fetch(url, {
  • Access to secretsline 119
    [Credential-related source omitted]

playwriter/src/cloud-scope.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 25
    describe('resolveCloudCookieUrls', () => {   test('defaults to the current page URL', () => {     expect(resolveCloudCookieUrls({ pageUrl: 'https://example.com/account?tab=profile' })).toMatchInlineSnapshot(`
  • Network accessline 26
    test('defaults to the current page URL', () => {     expect(resolveCloudCookieUrls({ pageUrl: 'https://example.com/account?tab=profile' })).toMatchInlineSnapshot(`       [
  • Network accessline 27
    expect(resolveCloudCookieUrls({ pageUrl: 'https://example.com/account?tab=profile' })).toMatchInlineSnapshot(`
  • Network accessline 28
    [         "https://example.com/account?tab=profile",       ]
  • Network accessline 29
    "https://example.com/account?tab=profile",
  • Network accessline 34
    test('uses explicit URLs when provided', () => {     expect(resolveCloudCookieUrls({       pageUrl: 'https://example.com/account',
  • Network accessline 35
    expect(resolveCloudCookieUrls({       pageUrl: 'https://example.com/account',       urls: ['https://example.com', 'https://api.example.com/login'],
  • Network accessline 36
    pageUrl: 'https://example.com/account',
  • Network accessline 37
    urls: ['https://example.com', 'https://api.example.com/login'],
  • Network accessline 38
    })).toMatchInlineSnapshot(`       [         "https://example.com/",
  • Network accessline 39
    [         "https://example.com/",         "https://api.example.com/login",
  • Network accessline 40
    "https://example.com/",
  • Network accessline 41
    "https://api.example.com/login",
  • Network accessline 53
    name: 'partitioned',           partitionKey: {             topLevelSite: 'https://example.com',
  • Network accessline 54
    partitionKey: {             topLevelSite: 'https://example.com',             hasCrossSiteAncestor: false,
  • Network accessline 55
    topLevelSite: 'https://example.com',
  • Network accessline 85
    "partitionKey": {               "hasCrossSiteAncestor": false,               "topLevelSite": "https://example.com",
  • Network accessline 86
    "hasCrossSiteAncestor": false,               "topLevelSite": "https://example.com",             },
  • Network accessline 87
    "topLevelSite": "https://example.com",

playwriter/src/cloud-scope.ts

  • Executable scriptline 1
    [Credential-related source omitted]
  • Access to secretsline 1
    [Credential-related source omitted]
  • Access to secretsline 74
    [Credential-related source omitted]
  • Access to secretsline 181
    [Credential-related source omitted]
  • Access to secretsline 183
    [Credential-related source omitted]

playwriter/src/create-logger.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 25
    // Batch buffer: accumulate log lines and flush periodically to reduce disk I/O   // under high CDP event throughput. See: https://github.com/remorses/playwriter/issues/96
  • Network accessline 26
    // under high CDP event throughput. See: https://github.com/remorses/playwriter/issues/96

playwriter/src/debugger-examples-types.ts

  • Executable scriptline 1
    Executable file

playwriter/src/debugger-examples.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 45
    await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })

playwriter/src/debugger.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 39
    * const dbg = new Debugger({ cdp })  *  * await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })
  • Network accessline 40
    *  * await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })  * // trigger the code path, then:
  • Network accessline 41
    * await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })
  • Network accessline 148
    *    * @param options - Breakpoint options    * @param options.file - Script URL (e.g. https://example.com/app.js)
  • Network accessline 149
    * @param options - Breakpoint options    * @param options.file - Script URL (e.g. https://example.com/app.js)    * @param options.line - Line number (1-based)
  • Network accessline 150
    * @param options.file - Script URL (e.g. https://example.com/app.js)
  • Network accessline 155
    * @example    * ```ts    * const id = await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })
  • Network accessline 156
    * ```ts    * const id = await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })    * // later:
  • Network accessline 157
    * const id = await dbg.setBreakpoint({ file: 'https://example.com/app.js', line: 42 })
  • Network accessline 161
    * // Conditional breakpoint - only pause when userId is 123    * await dbg.setBreakpoint({    *   file: 'https://example.com/app.js',
  • Network accessline 162
    * await dbg.setBreakpoint({    *   file: 'https://example.com/app.js',    *   line: 42,
  • Network accessline 163
    *   file: 'https://example.com/app.js',
  • Network accessline 206
    * ```ts    * const breakpoints = dbg.listBreakpoints()    * // [{ id: 'bp-123', file: 'https://example.com/index.js', line: 42 }]
  • Network accessline 207
    * const breakpoints = dbg.listBreakpoints()    * // [{ id: 'bp-123', file: 'https://example.com/index.js', line: 42 }]    * ```
  • Network accessline 208
    * // [{ id: 'bp-123', file: 'https://example.com/index.js', line: 42 }]
  • Network accessline 352
    * ```ts    * const location = await dbg.getLocation()    * console.log(location.url)          // 'https://example.com/src/index.js'
  • Network accessline 353
    * const location = await dbg.getLocation()    * console.log(location.url)          // 'https://example.com/src/index.js'    * console.log(location.lineNumber)   // 42
  • Network accessline 354
    * console.log(location.url)          // 'https://example.com/src/index.js'
  • Network accessline 532
    * // List all scripts    * const scripts = await dbg.listScripts()    * // [{ scriptId: '1', url: 'https://example.com/app.js' }, ...]
  • Network accessline 533
    * const scripts = await dbg.listScripts()    * // [{ scriptId: '1', url: 'https://example.com/app.js' }, ...]    *
  • Network accessline 534
    * // [{ scriptId: '1', url: 'https://example.com/app.js' }, ...]
  • Network accessline 536
    * // Search for specific files    * const handlers = await dbg.listScripts({ search: 'handler' })    * // [{ scriptId: '5', url: 'https://example.com/handlers.js' }]
  • Network accessline 537
    * const handlers = await dbg.listScripts({ search: 'handler' })    * // [{ scriptId: '5', url: 'https://example.com/handlers.js' }]    * ```
  • Network accessline 538
    * // [{ scriptId: '5', url: 'https://example.com/handlers.js' }]
  • Network accessline 586
    *    * // Skip all third-party scripts    * await dbg.setBlackboxPatterns({ patterns: ['^https://cdn\\.'] })
  • Network accessline 587
    * // Skip all third-party scripts    * await dbg.setBlackboxPatterns({ patterns: ['^https://cdn\\.'] })    *
  • Network accessline 588
    * await dbg.setBlackboxPatterns({ patterns: ['^https://cdn\\.'] })

playwriter/src/diff-utils.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/diff-utils.ts

  • Executable scriptline 1
    Executable file

playwriter/src/editor-examples.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 19
    const { content, totalLines } = await editor.read({     url: 'https://example.com/app.js',
  • Network accessline 20
    url: 'https://example.com/app.js',
  • Network accessline 25
    const { content: partial } = await editor.read({     url: 'https://example.com/app.js',
  • Network accessline 26
    url: 'https://example.com/app.js',
  • Network accessline 39
    await editor.edit({     url: 'https://example.com/app.js',
  • Network accessline 40
    url: 'https://example.com/app.js',
  • Network accessline 45
    const dryRunResult = await editor.edit({     url: 'https://example.com/app.js',
  • Network accessline 46
    url: 'https://example.com/app.js',
  • Network accessline 76
    const { content } = await editor.read({ url: 'https://example.com/app.js' })
  • Network accessline 79
    await editor.write({     url: 'https://example.com/app.js',
  • Network accessline 80
    url: 'https://example.com/app.js',
  • Network accessline 128
    await editor.edit({     url: 'https://example.com/styles.css',
  • Network accessline 129
    url: 'https://example.com/styles.css',

playwriter/src/editor.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 36
    *  * // Read a script  * const { content } = await editor.read({ url: 'https://example.com/app.js' })
  • Network accessline 37
    * // Read a script  * const { content } = await editor.read({ url: 'https://example.com/app.js' })  *
  • Network accessline 38
    * const { content } = await editor.read({ url: 'https://example.com/app.js' })
  • Network accessline 40
    * // Edit a script  * await editor.edit({  *   url: 'https://example.com/app.js',
  • Network accessline 41
    * await editor.edit({  *   url: 'https://example.com/app.js',  *   oldString: 'console.log("old")',
  • Network accessline 42
    *   url: 'https://example.com/app.js',
  • Network accessline 183
    * // Read by URL    * const { content, totalLines } = await editor.read({    *   url: 'https://example.com/app.js'
  • Network accessline 184
    * const { content, totalLines } = await editor.read({    *   url: 'https://example.com/app.js'    * })
  • Network accessline 185
    *   url: 'https://example.com/app.js'
  • Network accessline 187
    *    * // Read a CSS file    * const { content } = await editor.read({ url: 'https://example.com/styles.css' })
  • Network accessline 188
    * // Read a CSS file    * const { content } = await editor.read({ url: 'https://example.com/styles.css' })    *
  • Network accessline 189
    * const { content } = await editor.read({ url: 'https://example.com/styles.css' })
  • Network accessline 191
    * // Read lines 100-200    * const { content } = await editor.read({    *   url: 'https://example.com/app.js',
  • Network accessline 192
    * const { content } = await editor.read({    *   url: 'https://example.com/app.js',    *   offset: 100,
  • Network accessline 193
    *   url: 'https://example.com/app.js',
  • Network accessline 252
    * // Replace a string in JS    * await editor.edit({    *   url: 'https://example.com/app.js',
  • Network accessline 253
    * await editor.edit({    *   url: 'https://example.com/app.js',    *   oldString: 'const DEBUG = false',
  • Network accessline 254
    *   url: 'https://example.com/app.js',
  • Network accessline 259
    * // Edit CSS    * await editor.edit({    *   url: 'https://example.com/styles.css',
  • Network accessline 260
    * await editor.edit({    *   url: 'https://example.com/styles.css',    *   oldString: 'color: red',
  • Network accessline 261
    *   url: 'https://example.com/styles.css',

playwriter/src/executor.ts

  • Executable scriptline 1
    Executable file
  • Access to secretsline 888
    [Credential-related source omitted]
  • Network accessline 892
    try {       if (extensionId) {         const response = await fetch(`${httpBaseUrl}/extensions/status`, {
  • Network accessline 893
    if (extensionId) {         const response = await fetch(`${httpBaseUrl}/extensions/status`, {           signal: AbortSignal.timeout(2000),
  • Network accessline 894
    const response = await fetch(`${httpBaseUrl}/extensions/status`, {
  • Network accessline 897
    })         if (!response.ok) {           const fallback = await fetch(`${httpBaseUrl}/extension/status`, {
  • Network accessline 898
    if (!response.ok) {           const fallback = await fetch(`${httpBaseUrl}/extension/status`, {             signal: AbortSignal.timeout(2000),
  • Network accessline 899
    const fallback = await fetch(`${httpBaseUrl}/extension/status`, {
  • Network accessline 933
    const response = await fetch(`${httpBaseUrl}/extension/status`, {

playwriter/src/executor.unit.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 18
    it('returns true for awaited expressions', () => {     expect(shouldAutoReturn('await Promise.resolve(42)')).toBe(true)     expect(shouldAutoReturn('await page.goto("https://example.com")')).toBe(true)
  • Network accessline 19
    expect(shouldAutoReturn('await Promise.resolve(42)')).toBe(true)     expect(shouldAutoReturn('await page.goto("https://example.com")')).toBe(true)   })
  • Network accessline 20
    expect(shouldAutoReturn('await page.goto("https://example.com")')).toBe(true)
  • Network accessline 158
    expect(isPlaywrightChannelOwner({})).toBe(false)     expect(isPlaywrightChannelOwner([])).toBe(false)     expect(isPlaywrightChannelOwner({ url: 'https://example.com', status: 200 })).toBe(false)
  • Network accessline 159
    expect(isPlaywrightChannelOwner([])).toBe(false)     expect(isPlaywrightChannelOwner({ url: 'https://example.com', status: 200 })).toBe(false)   })
  • Network accessline 160
    expect(isPlaywrightChannelOwner({ url: 'https://example.com', status: 200 })).toBe(false)

playwriter/src/extension-connection.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 40
    it('completes the additive extension inventory handshake', async () => {     const response = await fetch(`http://127.0.0.1:${TEST_PORT}/extension/status`)
  • Network accessline 41
    const response = await fetch(`http://127.0.0.1:${TEST_PORT}/extension/status`)
  • Network accessline 56
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/'
  • Network accessline 57
    const testUrl = 'https://example.com/'
  • Network accessline 127
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 128
    const page = await browserContext.newPage()     await page.goto('https://example.com/')     await page.bringToFront()
  • Network accessline 129
    await page.goto('https://example.com/')
  • Network accessline 258
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     await page.goto('https://example.com/?context-menu-pin')
  • Network accessline 259
    const page = await browserContext.newPage()     await page.goto('https://example.com/?context-menu-pin')     await page.evaluate(() => {
  • Network accessline 260
    await page.goto('https://example.com/?context-menu-pin')
  • Network accessline 312
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     await page.goto('https://example.com/?share')
  • Network accessline 313
    const page = await browserContext.newPage()     await page.goto('https://example.com/?share')     await page.bringToFront()
  • Network accessline 314
    await page.goto('https://example.com/?share')
  • Network accessline 354
    }     const anchor = await browserContext.newPage()     await anchor.goto('https://example.com/?anchor')
  • Network accessline 355
    const anchor = await browserContext.newPage()     await anchor.goto('https://example.com/?anchor')     await toggleActiveTab(anchor)
  • Network accessline 356
    await anchor.goto('https://example.com/?anchor')
  • Network accessline 357
    await toggleActiveTab(anchor)     const other = await browserContext.newPage()     await other.goto('https://example.com/?other')
  • Network accessline 358
    const other = await browserContext.newPage()     await other.goto('https://example.com/?other')     await toggleActiveTab(other)
  • Network accessline 359
    await other.goto('https://example.com/?other')
  • Network accessline 368
    let sessionId: string | undefined     try {       const response = await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/new`, {
  • Network accessline 369
    try {       const response = await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/new`, {         method: 'POST',
  • Network accessline 370
    const response = await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/new`, {
  • Network accessline 388
    expect(remoteUrls[0]).toBe('https://example.com/?anchor')
  • Network accessline 389
    expect(remoteUrls).toContain('https://example.com/?other')
  • Network accessline 391
    const remoteOther = remoteContext.pages().find((page) => {         return page.url() === 'https://example.com/?other'
  • Network accessline 392
    return page.url() === 'https://example.com/?other'
  • Network accessline 396
    const created = await remoteContext.newPage()       await created.goto('https://example.com/?created')
  • Network accessline 397
    await created.goto('https://example.com/?created')
  • Network accessline 440
    })       if (sessionId) {         await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/delete`, {
  • Network accessline 441
    if (sessionId) {         await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/delete`, {           method: 'POST',
  • Network accessline 442
    await fetch(`http://127.0.0.1:${TEST_PORT}/cli/session/delete`, {
  • Network accessline 447
    }       const createdPages = browserContext.pages().filter((page) => {         return page.url() === 'https://example.com/?created'
  • Network accessline 448
    const createdPages = browserContext.pages().filter((page) => {         return page.url() === 'https://example.com/?created'       })
  • Network accessline 449
    return page.url() === 'https://example.com/?created'
  • Network accessline 464
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 465
    const page = await browserContext.newPage()     await page.goto('https://example.com/')     await page.bringToFront()
  • Network accessline 466
    await page.goto('https://example.com/')
  • Network accessline 476
    }     const recordingCount = async () => {       const response = await fetch(`http://127.0.0.1:${TEST_PORT}/recorder/status`)
  • Network accessline 477
    const recordingCount = async () => {       const response = await fetch(`http://127.0.0.1:${TEST_PORT}/recorder/status`)       const status = (await response.json()) as { recordings: Array<{ recordingId: string }> }
  • Network accessline 478
    const response = await fetch(`http://127.0.0.1:${TEST_PORT}/recorder/status`)
  • Network accessline 506
    const relayPost = async (route: string) => {       await fetch(`http://127.0.0.1:${TEST_PORT}${route}`, {
  • Network accessline 507
    await fetch(`http://127.0.0.1:${TEST_PORT}${route}`, {
  • Network accessline 531
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     const testUrl = 'https://example.com/?toolbar-pass-through'
  • Network accessline 532
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/?toolbar-pass-through'     await page.goto(testUrl)
  • Network accessline 533
    const testUrl = 'https://example.com/?toolbar-pass-through'
  • Network accessline 581
    const recorderResponse = await fetch(`http://127.0.0.1:${TEST_PORT}/recorder/status`)
  • Network accessline 624
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/persistent'
  • Network accessline 625
    const testUrl = 'https://example.com/persistent'
  • Network accessline 689
    const page = await browserContext.newPage()     const initialUrl = 'https://example.com/'
  • Network accessline 690
    const initialUrl = 'https://example.com/'
  • Network accessline 718
    const newUrl = 'https://example.org/'
  • Network accessline 737
    const pageA = await browserContext.newPage()     await pageA.goto('https://example.com/tab-a')
  • Network accessline 738
    await pageA.goto('https://example.com/tab-a')
  • Network accessline 746
    const pageB = await browserContext.newPage()     await pageB.goto('https://example.com/tab-b')
  • Network accessline 747
    await pageB.goto('https://example.com/tab-b')
  • Network accessline 799
    {           "title": "Example Domain",           "url": "https://example.com/tab-a",
  • Network accessline 800
    "title": "Example Domain",           "url": "https://example.com/tab-a",         },
  • Network accessline 801
    "url": "https://example.com/tab-a",
  • Network accessline 803
    {           "title": "Example Domain",           "url": "https://example.com/tab-b",
  • Network accessline 804
    "title": "Example Domain",           "url": "https://example.com/tab-b",         },
  • Network accessline 805
    "url": "https://example.com/tab-b",
  • Network accessline 826
    const pageA = await browserContext.newPage()     await pageA.goto('https://example.com/close-warning-a')
  • Network accessline 827
    await pageA.goto('https://example.com/close-warning-a')
  • Network accessline 833
    const pageB = await browserContext.newPage()     await pageB.goto('https://example.com/close-warning-b')
  • Network accessline 834
    await pageB.goto('https://example.com/close-warning-b')
  • Network accessline 848
    })     expect((storedCloseResult as any).isError).not.toBe(true)     expect((storedCloseResult as any).content[0].text).toMatchInlineSnapshot(`"[WARNING] Page closed (url: https://example.com/close-warning-a) for state.page. Assign a new op
  • Network accessline 850
    expect((storedCloseResult as any).content[0].text).toMatchInlineSnapshot(`"[WARNING] Page closed (url: https://example.com/close-warning-a) for state.page. Assign a new open page to state.page before reusing it, e.g. state.page = await cont
  • Network accessline 875
    const page = await browserContext.newPage()     const targetUrl = 'https://example.com/late-enable'
  • Network accessline 876
    const targetUrl = 'https://example.com/late-enable'
  • Network accessline 909
    await page.goto('https://example.com/disconnect-test')
  • Network accessline 1034
    const page = await testCtx!.browserContext.newPage()     await page.goto('https://example.com/auto-reconnect-test')
  • Network accessline 1035
    await page.goto('https://example.com/auto-reconnect-test')
  • Network accessline 1118
    const page = await browserContext.newPage()     const targetUrl = 'https://example.com/multi-context-stability'
  • Network accessline 1119
    const targetUrl = 'https://example.com/multi-context-stability'
  • Network accessline 1198
    const page = await browserContext.newPage()     const targetUrl = 'https://example.com/sw-test'
  • Network accessline 1199
    const targetUrl = 'https://example.com/sw-test'
  • Network accessline 1225
    const page = await browserContext.newPage()     const targetUrl = 'https://example.com/repeated-test'
  • Network accessline 1226
    const targetUrl = 'https://example.com/repeated-test'
  • Network accessline 1253
    const page = await browserContext.newPage()     const targetUrl = 'https://example.com/concurrent-test'
  • Network accessline 1254
    const targetUrl = 'https://example.com/concurrent-test'
  • Network accessline 1310
    const serviceWorker = await getExtensionServiceWorker(browserContext)     const page = await browserContext.newPage()     await page.goto('https://example.com/?handshake-race')
  • Network accessline 1311
    const page = await browserContext.newPage()     await page.goto('https://example.com/?handshake-race')     await page.bringToFront()
  • Network accessline 1312
    await page.goto('https://example.com/?handshake-race')

playwriter/src/ffmpeg.ts

  • Executable scriptline 1
    Executable file

playwriter/src/ghost-browser.ts

  • Executable scriptline 1
    Executable file

playwriter/src/ghost-cursor-client.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 84
    // Animation curves from Emil Kowalski's guidelines (https://animations.dev):
  • Network accessline 308
    if (runtime.options.style === 'minimal') {     const triangleSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-1 -1 26 26"><path fill="white" stroke="${runtime.options.color}" stroke-width="1.5" stroke-linejoin
  • Network accessline 309
    const triangleSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="-1 -1 26 26"><path fill="white" stroke="${runtime.options.color}" stroke-width="1.5" stroke-linejoin="round" d="m23.284 19.124l-6.866-6.895a.4.4 0 
  • Network accessline 331
    const parsed = new DOMParser().parseFromString(markup, 'image/svg+xml')   const svg = parsed.documentElement   if (svg.namespaceURI !== 'http://www.w3.org/2000/svg' || svg.localName !== 'svg') {
  • Network accessline 332
    const svg = parsed.documentElement   if (svg.namespaceURI !== 'http://www.w3.org/2000/svg' || svg.localName !== 'svg') {     return
  • Network accessline 333
    if (svg.namespaceURI !== 'http://www.w3.org/2000/svg' || svg.localName !== 'svg') {

playwriter/src/ghost-cursor-controller.ts

  • Executable scriptline 1
    Executable file

playwriter/src/ghost-cursor.ts

  • Executable scriptline 1
    Executable file

playwriter/src/htmlrewrite.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 27
    <div name="Log in" data-framer-name="Login" data-highlight="true">               <div data-framer-name="Start for free" name="Start for free">                <a name="Start for free" data-signup-debug-id="header-sign-up" data-framer-name="L
  • Network accessline 28
    <div data-framer-name="Start for free" name="Start for free">                <a name="Start for free" data-signup-debug-id="header-sign-up" data-framer-name="Label" data-highlight="true" href="https://framer.com/r/login">                 <d
  • Network accessline 29
    <a name="Start for free" data-signup-debug-id="header-sign-up" data-framer-name="Label" data-highlight="true" href="https://framer.com/r/login">
  • Network accessline 38
    <div name="Sign up" data-signup-debug-id="header-sign-up" data-framer-name="Signup" data-highlight="true">               <div data-framer-name="Start for free" name="Start for free">                <a name="Start for free" data-signup-debug
  • Network accessline 39
    <div data-framer-name="Start for free" name="Start for free">                <a name="Start for free" data-signup-debug-id="header-sign-up" data-framer-name="Button" data-highlight="true" href="https://www.framer.com/r/signup/">            
  • Network accessline 40
    <a name="Start for free" data-signup-debug-id="header-sign-up" data-framer-name="Button" data-highlight="true" href="https://www.framer.com/r/signup/">
  • Network accessline 596
    </div>            <div data-framer-appear-id="1t92ft3" data-framer-name="Buttons">             <a data-signup-debug-id="hero-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 597
    <div data-framer-appear-id="1t92ft3" data-framer-name="Buttons">             <a data-signup-debug-id="hero-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">              <div d
  • Network accessline 598
    <a data-signup-debug-id="hero-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 601
    </div>             </a>             <a data-signup-debug-id="hero-sign-up" data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 602
    </a>             <a data-signup-debug-id="hero-sign-up" data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">              <div data-framer-name="Default" data-framer-component-type="RichText
  • Network accessline 603
    <a data-signup-debug-id="hero-sign-up" data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 1756
    <p>                       Today, we’re shipping an update where we offer a free custom domain for the first year when you upgrade your site to a yearly plan. We’ve partnered with                       <a href="https://www.hover.com/" target
  • Network accessline 1757
    Today, we’re shipping an update where we offer a free custom domain for the first year when you upgrade your site to a yearly plan. We’ve partnered with                       <a href="https://www.hover.com/" target="_blank">Hover</a>       
  • Network accessline 1758
    <a href="https://www.hover.com/" target="_blank">Hover</a>
  • Network accessline 1778
    <p>                         Your domain and its subscription will be managed through                         <a href="https://www.hover.com/" target="_blank">Hover</a>
  • Network accessline 1779
    Your domain and its subscription will be managed through                         <a href="https://www.hover.com/" target="_blank">Hover</a>                        </p>
  • Network accessline 1780
    <a href="https://www.hover.com/" target="_blank">Hover</a>
  • Network accessline 4193
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4194
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4195
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4198
    </div>             </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4199
    </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4200
    <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4203
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4204
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4205
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/experts/">
  • Network accessline 4217
    <div data-framer-name="Experts Desktop 1">                 <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4218
    <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4219
    <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4245
    </div>                 <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4246
    <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4247
    <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4266
    </div>                 <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4267
    <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">                   <div data-border="true" data-framer-name=
  • Network accessline 4268
    <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4294
    </div>                 <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4295
    <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">                   <div data-border="true" data-framer-name="Visual
  • Network accessline 4296
    <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4326
    <div data-framer-name="Experts Desktop 2">                 <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4327
    <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 4328
    <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4354
    </div>                 <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4355
    <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4356
    <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4382
    </div>                 <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4383
    <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4384
    <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4410
    </div>                 <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4411
    <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">                   <div data-border="true" data-framer-name="Vis
  • Network accessline 4412
    <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4462
    <div data-framer-name="Experts Tablet 1">                 <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4463
    <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4464
    <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4490
    </div>                 <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4491
    <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4492
    <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4511
    </div>                 <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4512
    <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">                   <div data-border="true" data-framer-name=
  • Network accessline 4513
    <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4539
    </div>                 <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4540
    <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">                   <div data-border="true" data-framer-name="Visual
  • Network accessline 4541
    <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4571
    <div data-framer-name="Experts Tablet 2">                 <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4572
    <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 4573
    <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4599
    </div>                 <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4600
    <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4601
    <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4627
    </div>                 <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4628
    <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4629
    <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4655
    </div>                 <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4656
    <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">                   <div data-border="true" data-framer-name="Vis
  • Network accessline 4657
    <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4707
    <div data-framer-name="Experts Phone 1">                 <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4708
    <div data-framer-name="Trueform" name="Trueform">                  <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4709
    <a name="Trueform" data-framer-name="Expert" href="https://www.framer.com/@trueform/">
  • Network accessline 4718
    </div>                 <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4719
    <div data-framer-name="Alex Aperios" name="Alex Aperios">                  <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4720
    <a name="Alex Aperios" data-framer-name="Expert" href="https://www.framer.com/@alex-aperios/">
  • Network accessline 4729
    </div>                 <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4730
    <div data-framer-name="Analogue Agency" name="Analogue Agency">                  <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">                   <div data-border="true" data-framer-name=
  • Network accessline 4731
    <a name="Analogue Agency" data-framer-name="Expert" href="https://www.framer.com/@analogueagency/">
  • Network accessline 4740
    </div>                 <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4741
    <div data-framer-name="Fabian Albert" name="Fabian Albert">                  <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">                   <div data-border="true" data-framer-name="Visual
  • Network accessline 4742
    <a name="Fabian Albert" data-framer-name="Expert" href="https://www.framer.com/@fabian-albert/">
  • Network accessline 4755
    <div data-framer-name="Experts Phone 2">                 <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4756
    <div data-framer-name="Allsite Studio" name="Allsite Studio">                  <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 4757
    <a name="Allsite Studio" data-framer-name="Expert" href="https://www.framer.com/@ben-libor/">
  • Network accessline 4766
    </div>                 <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4767
    <div data-framer-name="Aerolab" name="Aerolab">                  <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4768
    <a name="Aerolab" data-framer-name="Expert" href="https://www.framer.com/@aerolab/">
  • Network accessline 4777
    </div>                 <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4778
    <div data-framer-name="Adriano Reis" name="Adriano Reis">                  <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 4779
    <a name="Adriano Reis" data-framer-name="Expert" href="https://www.framer.com/@adrianoreis/">
  • Network accessline 4788
    </div>                 <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4789
    <div data-framer-name="Deserve Studio" name="Deserve Studio">                  <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">                   <div data-border="true" data-framer-name="Vis
  • Network accessline 4790
    <a name="Deserve Studio" data-framer-name="Expert" href="https://www.framer.com/@deservestudio/">
  • Network accessline 4825
    </div>            <div data-framer-name="Buttons">             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4826
    <div data-framer-name="Buttons">             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Default" data-framer-component-ty
  • Network accessline 4827
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4830
    </div>             </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4831
    </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4832
    <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4835
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4836
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4837
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 4840
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4841
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4842
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4845
    </div>             </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4846
    </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4847
    <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4850
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4851
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4852
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 4855
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4856
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4857
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4860
    </div>             </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4861
    </a>             <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4862
    <a data-framer-name="Phone" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4865
    </div>             </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4866
    </a>             <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Default" data-framer-component-type="RichTextContainer">
  • Network accessline 4867
    <a data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://www.framer.com/marketplace/components/">
  • Network accessline 4878
    <li aria-hidden="false">                <div>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 4879
    <div>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 4880
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 4907
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 4908
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 4909
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 4941
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 4942
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 4943
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 4975
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 4976
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 4977
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5004
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5005
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5006
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5038
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5039
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5040
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5080
    <li aria-hidden="false">                <div>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5081
    <div>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5082
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5109
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 5110
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5111
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 5143
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 5144
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5145
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 5172
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 5173
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5174
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 5201
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 5202
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5203
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 5235
    </div>                 </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 5236
    </a>                 <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">                  <div data-border="true" data-framer-name="Visual">
  • Network accessline 5237
    <a data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 5280
    <div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5281
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5282
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5311
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5312
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5313
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5342
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5343
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5344
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5378
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5379
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5380
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5414
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5415
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5416
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5450
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5451
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5452
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5486
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5487
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5488
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5517
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5518
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5519
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5548
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5549
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5550
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5584
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5585
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5586
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5620
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5621
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5622
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5656
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5657
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5658
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5692
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5693
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">                   <div data-border="true" data-framer-name="Visua
  • Network accessline 5694
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5723
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5724
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">                   <div data-border="true" data-framer-name="Visua
  • Network accessline 5725
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5758
    <div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5759
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5760
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/image-slider/">
  • Network accessline 5789
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5790
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5791
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/milo/">
  • Network accessline 5825
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5826
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5827
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/notion/">
  • Network accessline 5861
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5862
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5863
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/hover-image-zoom/">
  • Network accessline 5892
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5893
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5894
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/archer/">
  • Network accessline 5928
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5929
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 5930
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/workshop/">
  • Network accessline 5964
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 5965
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">                   <div data-border="true" data-framer-name="Visua
  • Network accessline 5966
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/digital-rotary-radio/">
  • Network accessline 6003
    <div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6004
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6005
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6039
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6040
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6041
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6075
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6076
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 6077
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6106
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6107
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 6108
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6137
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6138
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6139
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6168
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6169
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6170
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6199
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6200
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6201
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6235
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6236
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6237
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6271
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6272
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6273
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6307
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6308
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6309
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6343
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6344
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6345
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6379
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6380
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6381
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6415
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6416
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6417
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6446
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6447
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6448
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6481
    <div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6482
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6483
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/apex-films/">
  • Network accessline 6517
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6518
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">                   <div data-border="true" data-framer-name="Visual"
  • Network accessline 6519
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/flipcard-component/">
  • Network accessline 6548
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6549
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6550
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/animated-gradient/">
  • Network accessline 6579
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6580
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6581
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/json-sync/">
  • Network accessline 6615
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6616
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6617
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/templates/baseform/">
  • Network accessline 6651
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6652
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6653
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/plugins/asset-manager/">
  • Network accessline 6687
    </div>                 <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6688
    <div data-framer-name="Milo" name="Milo">                  <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">                   <div data-border="true" data-framer-name="Visual">
  • Network accessline 6689
    <a name="Milo" data-framer-name="Pause" href="https://www.framer.com/marketplace/components/videoplayer/">
  • Network accessline 6734
    </div>          <div data-framer-name="Buttons">           <a data-signup-debug-id="bottom-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 6735
    <div data-framer-name="Buttons">           <a data-signup-debug-id="bottom-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">            <div data-framer-name="Default" data-fra
  • Network accessline 6736
    <a data-signup-debug-id="bottom-sign-up" data-framer-name="Regular" data-highlight="true" data-reset="button" href="https://framer.com/r/signup">
  • Network accessline 6754
    <a data-framer-name="On" data-highlight="true" href="./" data-framer-page-link-current="true"></a>             <div>              <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>
  • Network accessline 6755
    <div>              <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>              <a aria-label="Threads" data-framer-name="Threads" href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 6756
    <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>
  • Network accessline 6757
    <a aria-label="Threads" data-framer-name="Threads" href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 6758
    <a aria-label="TikTok" data-framer-name="TikTok" href="https://www.tiktok.com/@framer" target="_blank"></a>
  • Network accessline 6759
    <a aria-label="Instagram" data-framer-name="Instagram" href="https://www.instagram.com/framer/" target="_blank"></a>
  • Network accessline 6760
    <a aria-label="LinkedIn" data-framer-name="LinkedIn" href="https://www.linkedin.com/company/framer/" target="_blank"></a>
  • Network accessline 6761
    <a aria-label="YouTube" data-framer-name="YouTube" href="https://www.youtube.com/@Framer" target="_blank"></a>
  • Network accessline 6762
    </div>             <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">
  • Network accessline 6763
    <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">               <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6764
    <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">
  • Network accessline 6948
    </div>             </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 6949
    </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6950
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 6953
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 6954
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6955
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 6958
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 6959
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6960
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 6963
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 6964
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6965
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 6968
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 6969
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 6970
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 7109
    <a data-framer-name="On" data-highlight="true" href="./" data-framer-page-link-current="true"></a>             <div>              <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>
  • Network accessline 7110
    <div>              <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>              <a aria-label="Threads" data-framer-name="Threads" href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 7111
    <a aria-label="Twitter / X" data-framer-name="X" href="https://x.com/framer" target="_blank"></a>
  • Network accessline 7112
    <a aria-label="Threads" data-framer-name="Threads" href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 7113
    <a aria-label="TikTok" data-framer-name="TikTok" href="https://www.tiktok.com/@framer" target="_blank"></a>
  • Network accessline 7114
    <a aria-label="Instagram" data-framer-name="Instagram" href="https://www.instagram.com/framer/" target="_blank"></a>
  • Network accessline 7115
    <a aria-label="LinkedIn" data-framer-name="LinkedIn" href="https://www.linkedin.com/company/framer/" target="_blank"></a>
  • Network accessline 7116
    <a aria-label="YouTube" data-framer-name="YouTube" href="https://www.youtube.com/@Framer" target="_blank"></a>
  • Network accessline 7117
    </div>             <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">
  • Network accessline 7118
    <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">               <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7119
    <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">
  • Network accessline 7303
    </div>             </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 7304
    </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7305
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 7308
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 7309
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7310
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 7313
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 7314
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7315
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 7318
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 7319
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7320
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 7323
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 7324
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7325
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 7464
    <a data-framer-name="On" data-highlight="true" href="./" data-framer-page-link-current="true"></a>             <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank
  • Network accessline 7465
    <div data-framer-name="Variant 1">              <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">               <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7466
    <a data-framer-name="Loading" href="https://www.framerstatus.com/" target="_blank">
  • Network accessline 7639
    </div>             </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 7640
    </div>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7641
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/templates/">
  • Network accessline 7644
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 7645
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7646
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/components/">
  • Network accessline 7649
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 7650
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7651
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/plugins/">
  • Network accessline 7654
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 7655
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7656
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/vectors/">
  • Network accessline 7659
    </div>             </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 7660
    </a>             <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">              <div data-framer-name="Item" data-framer-component-type="RichTextContainer">
  • Network accessline 7661
    <a data-framer-name="Label" data-highlight="true" href="https://www.framer.com/marketplace/">
  • Network accessline 7797
    </div>          <div>           <a href="https://x.com/framer" target="_blank"></a>
  • Network accessline 7798
    <div>           <a href="https://x.com/framer" target="_blank"></a>           <a href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 7799
    <a href="https://x.com/framer" target="_blank"></a>
  • Network accessline 7800
    <a href="https://www.threads.com/@framer" target="_blank"></a>
  • Network accessline 7801
    <a href="https://www.tiktok.com/@framer" target="_blank"></a>
  • Network accessline 7802
    <a href="https://www.instagram.com/framer/" target="_blank"></a>
  • Network accessline 7803
    <a href="https://www.linkedin.com/company/framer/" target="_blank"></a>
  • Network accessline 7804
    <a href="https://www.youtube.com/@Framer" target="_blank"></a>

playwriter/src/htmlrewrite.ts

  • Executable scriptline 1
    Executable file

playwriter/src/index.ts

  • Executable scriptline 1
    Executable file

playwriter/src/kill-port.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 3
    *  * This mirrors the approach used by the `kill-port-process` npm package:  * https://github.com/hilleer/kill-port-process
  • Network accessline 4
    * This mirrors the approach used by the `kill-port-process` npm package:  * https://github.com/hilleer/kill-port-process  *
  • Network accessline 5
    * https://github.com/hilleer/kill-port-process

playwriter/src/kitty-graphics.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/kitty-graphics.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 9
    // Only emits when AGENT_GRAPHICS env var contains 'kitty', signaling that // an agent is intercepting stdout and can handle Kitty Graphics Protocol. // See: https://github.com/remorses/kitty-graphics-agent
  • Network accessline 11
    // See: https://github.com/remorses/kitty-graphics-agent

playwriter/src/locator-selector.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/mcp-client.ts

  • Executable scriptline 1
    Executable file

playwriter/src/mcp.ts

  • Executable scriptline 1
    Executable file
  • Access to secretsline 45
    [Credential-related source omitted]
  • Network accessline 53
    return `${httpBaseUrl}/mcp-log`   }   return `http://127.0.0.1:${RELAY_PORT}/mcp-log`
  • Network accessline 54
    }   return `http://127.0.0.1:${RELAY_PORT}/mcp-log` }
  • Network accessline 55
    return `http://127.0.0.1:${RELAY_PORT}/mcp-log`
  • Access to secretsline 61
    [Credential-related source omitted]
  • Network accessline 63
    headers['Authorization'] = `Bearer ${token}`     }     await fetch(getLogServerUrl(), {
  • Network accessline 64
    }     await fetch(getLogServerUrl(), {       method: 'POST',
  • Network accessline 65
    await fetch(getLogServerUrl(), {
  • Network accessline 177
    [Credential-related source omitted]
  • Network accessline 178
    [Credential-related source omitted]
  • Network accessline 179
    const response = await fetch(versionUrl, { headers, signal: AbortSignal.timeout(3000) })
  • Network accessline 205
    server.resource(   'debugger-api',   'https://playwriter.dev/resources/debugger-api.md',
  • Network accessline 206
    'debugger-api',   'https://playwriter.dev/resources/debugger-api.md',   { mimeType: 'text/plain' },
  • Network accessline 207
    'https://playwriter.dev/resources/debugger-api.md',
  • Network accessline 212
    const content = fs.readFileSync(path.join(packageDir, 'dist', 'debugger-api.md'), 'utf-8')     return {       contents: [{ uri: 'https://playwriter.dev/resources/debugger-api.md', text: content, mimeType: 'text/plain' }],
  • Network accessline 213
    return {       contents: [{ uri: 'https://playwriter.dev/resources/debugger-api.md', text: content, mimeType: 'text/plain' }],     }
  • Network accessline 214
    contents: [{ uri: 'https://playwriter.dev/resources/debugger-api.md', text: content, mimeType: 'text/plain' }],
  • Network accessline 219
    server.resource(   'editor-api',   'https://playwriter.dev/resources/editor-api.md',
  • Network accessline 220
    'editor-api',   'https://playwriter.dev/resources/editor-api.md',   { mimeType: 'text/plain' },
  • Network accessline 221
    'https://playwriter.dev/resources/editor-api.md',
  • Network accessline 226
    const content = fs.readFileSync(path.join(packageDir, 'dist', 'editor-api.md'), 'utf-8')     return {       contents: [{ uri: 'https://playwriter.dev/resources/editor-api.md', text: content, mimeType: 'text/plain' }],
  • Network accessline 227
    return {       contents: [{ uri: 'https://playwriter.dev/resources/editor-api.md', text: content, mimeType: 'text/plain' }],     }
  • Network accessline 228
    contents: [{ uri: 'https://playwriter.dev/resources/editor-api.md', text: content, mimeType: 'text/plain' }],
  • Network accessline 233
    server.resource(   'styles-api',   'https://playwriter.dev/resources/styles-api.md',
  • Network accessline 234
    'styles-api',   'https://playwriter.dev/resources/styles-api.md',   { mimeType: 'text/plain' },
  • Network accessline 235
    'https://playwriter.dev/resources/styles-api.md',
  • Network accessline 240
    const content = fs.readFileSync(path.join(packageDir, 'dist', 'styles-api.md'), 'utf-8')     return {       contents: [{ uri: 'https://playwriter.dev/resources/styles-api.md', text: content, mimeType: 'text/plain' }],
  • Network accessline 241
    return {       contents: [{ uri: 'https://playwriter.dev/resources/styles-api.md', text: content, mimeType: 'text/plain' }],     }
  • Network accessline 242
    contents: [{ uri: 'https://playwriter.dev/resources/styles-api.md', text: content, mimeType: 'text/plain' }],
  • Access to secretsline 374
    [Credential-related source omitted]

playwriter/src/on-mouse-action.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/package-paths.ts

  • Executable scriptline 1
    Executable file

playwriter/src/page-markdown.ts

  • Executable scriptline 1
    Executable file

playwriter/src/performance-examples.ts

  • Executable scriptline 1
    Executable file

playwriter/src/playwright-import.ts

  • Executable scriptline 1
    Executable file

playwriter/src/popup-relocation.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 143
    // Chrome 155 omits the inherited group's change event; bundled Chromium 145 emits one.   // Chrome 155 event log: https://github.com/remorses/playwriter/issues/133#issuecomment-6278536708
  • Network accessline 144
    // Chrome 155 event log: https://github.com/remorses/playwriter/issues/133#issuecomment-6278536708

playwriter/src/protocol.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/protocol.ts

  • Executable scriptline 1
    Executable file

playwriter/src/react-source.ts

  • Executable scriptline 1
    Executable file

playwriter/src/recorder-prompt.md

  • Network accessline 23
    Or fetch https://playwriter.dev/SKILL.md (same content). Always use the **playwriter**
  • Network accessline 145
    Use the [Agent Skills](https://agentskills.io) default locations, not a
  • Network accessline 174
    playwriter -s 1 -e 'state.page = await context.newPage(); await state.page.goto("https://directory.example.com/submit")'
  • Network accessline 180
    playwriter -s 1 -e 'const name = "Acme"; await state.page.getByRole("textbox", { name: "Product name" }).fill(name)' playwriter -s 1 -e 'const url = "https://acme.com"; await state.page.getByRole("textbox", { name: "Website URL" }).fill(url
  • Network accessline 181
    playwriter -s 1 -e 'const url = "https://acme.com"; await state.page.getByRole("textbox", { name: "Website URL" }).fill(url)'
  • Network accessline 265
    return await this.page.evaluate(       async ({ path, method, body }) => {         const res = await fetch(path, {
  • Network accessline 266
    async ({ path, method, body }) => {         const res = await fetch(path, {           method,
  • Network accessline 267
    const res = await fetch(path, {
  • Network accessline 306
    playwriter -s 1 -e 'const { DirectoryClient } = await import("./.agents/skills/submit-to-directory/sdk.js"); state.page ??= await context.newPage(); const client = new DirectoryClient({ page: state.page }); console.log(await client.submitPr
  • Network accessline 314
    - Use the safe structure from recorded `network` events. Treat redacted,   truncated, or omitted values as parameters that must be supplied or fetched. - Open the site origin first so `fetch('/api/...')` is same-origin.
  • Network accessline 315
    truncated, or omitted values as parameters that must be supplied or fetched. - Open the site origin first so `fetch('/api/...')` is same-origin. - If a call needs a prior id or csrf token, fetch that in another method and
  • Network accessline 316
    - Open the site origin first so `fetch('/api/...')` is same-origin.
  • Network accessline 323
    bot, a cron job), not only replay inside `playwriter -e`. Write `sdk.ts` and connect with the `playwriter` package. Docs: https://playwriter.dev/docs/sessions#node-api
  • Network accessline 325
    https://playwriter.dev/docs/sessions#node-api
  • Network accessline 339
    // the connection never closes tabs: `await using page` closes the tab this function opened.   await using page = await connection.browser.contexts()[0].newPage()   await page.goto('https://directory.example.com', { waitUntil: 'domcontentlo
  • Network accessline 340
    await using page = await connection.browser.contexts()[0].newPage()   await page.goto('https://directory.example.com', { waitUntil: 'domcontentloaded' })   return await page.evaluate(async () => {
  • Network accessline 341
    await page.goto('https://directory.example.com', { waitUntil: 'domcontentloaded' })   return await page.evaluate(async () => {     const res = await fetch('/api/products', { credentials: 'include' })
  • Network accessline 342
    return await page.evaluate(async () => {     const res = await fetch('/api/products', { credentials: 'include' })     if (!res.ok) throw new Error(`GET /api/products failed: ${res.status} ${await res.text()}`)
  • Network accessline 343
    const res = await fetch('/api/products', { credentials: 'include' })

playwriter/src/recorder.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 22
    const TEST_PORT = 19997 const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 23
    const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 29
    async function deleteSession(sessionId: string) {   await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 30
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 39
    [Credential-related source omitted]
  • Network accessline 40
    [Credential-related source omitted]
  • Network accessline 41
    [Credential-related source omitted]
  • Access to secretsline 41
    [Credential-related source omitted]
  • Network accessline 44
    [Credential-related source omitted]
  • Network accessline 45
    [Credential-related source omitted]
  • Network accessline 46
    [Credential-related source omitted]
  • Access to secretsline 46
    [Credential-related source omitted]
  • Network accessline 169
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 170
    await page.goto('https://example.com/')
  • Network accessline 178
    const sessionResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 187
    const startResponse = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 197
    const duplicateResponse = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 242
    document.body.appendChild(toast)       toast.textContent = 'You have reached your concurrent generation limit'       await fetch('/?same-origin-get=kept')
  • Network accessline 243
    toast.textContent = 'You have reached your concurrent generation limit'       await fetch('/?same-origin-get=kept')       await fetch('https://www.iana.org/?cross-origin-get-dropped').catch(() => {})
  • Network accessline 244
    await fetch('/?same-origin-get=kept')
  • Network accessline 245
    await fetch('https://www.iana.org/?cross-origin-get-dropped').catch(() => {})
  • Network accessline 246
    [Credential-related source omitted]
  • Access to secretsline 246
    [Credential-related source omitted]
  • Network accessline 262
    const statusResponse = await fetch(`${SERVER_URL}/recorder/status`)
  • Network accessline 268
    const stopResponse = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 341
    const stopAgainResponse = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 349
    const eventsResponse = await fetch(`${SERVER_URL}/recorder/events/${start.recordingId}`)
  • Network accessline 357
    const start2Response = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 369
    const stop2Response = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 385
    const start3Response = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 404
    await cdp.send('Input.insertText', { text: 'c' })     await new Promise((r) => setTimeout(r, 1500))     const stop3Response = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 405
    await new Promise((r) => setTimeout(r, 1500))     const stop3Response = await fetch(`${SERVER_URL}/recorder/stop`, {       method: 'POST',
  • Network accessline 406
    const stop3Response = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 427
    const page = await browserContext.newPage()     await page.goto('https://example.com/?second-client')
  • Network accessline 428
    await page.goto('https://example.com/?second-client')
  • Network accessline 435
    const sessionResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 443
    const startResponse = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 479
    const stopResponse = await fetch(`${SERVER_URL}/recorder/stop`, {
  • Network accessline 500
    const page = await browserContext.newPage()     await page.goto('https://example.com/?binding-owner')
  • Network accessline 501
    await page.goto('https://example.com/?binding-owner')
  • Network accessline 552
    const sessionResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 556
    })     const session = (await sessionResponse.json()) as { id: string }     const startResponse = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 557
    const session = (await sessionResponse.json()) as { id: string }     const startResponse = await fetch(`${SERVER_URL}/recorder/start`, {       method: 'POST',
  • Network accessline 558
    const startResponse = await fetch(`${SERVER_URL}/recorder/start`, {
  • Network accessline 616
    const stopResponse = await fetch(`${SERVER_URL}/recorder/stop`, {

playwriter/src/relay-client.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 22
    export const PLAYWRITER_EXTENSION_URL =   'https://chromewebstore.google.com/detail/playwriter/jfeammnjpkecdekppnclgkkffahnhfhe'
  • Network accessline 23
    'https://chromewebstore.google.com/detail/playwriter/jfeammnjpkecdekppnclgkkffahnhfhe'
  • Network accessline 54
    const response = await fetch(`http://127.0.0.1:${port}/version`, {
  • Network accessline 94
    ): Promise<{ connected: boolean; activeTargets: number; playwriterVersion: string | null } | null> {   try {     const response = await fetch(`http://127.0.0.1:${port}/extension/status`, {
  • Network accessline 95
    try {     const response = await fetch(`http://127.0.0.1:${port}/extension/status`, {       signal: AbortSignal.timeout(500),
  • Network accessline 96
    const response = await fetch(`http://127.0.0.1:${port}/extension/status`, {
  • Network accessline 108
    export async function getExtensionsStatus(port: number = RELAY_PORT): Promise<ExtensionStatus[]> {   try {     const response = await fetch(`http://127.0.0.1:${port}/extensions/status`, {
  • Network accessline 109
    try {     const response = await fetch(`http://127.0.0.1:${port}/extensions/status`, {       signal: AbortSignal.timeout(2000),
  • Network accessline 110
    const response = await fetch(`http://127.0.0.1:${port}/extensions/status`, {
  • Network accessline 112
    })     if (!response.ok) {       const fallback = await fetch(`http://127.0.0.1:${port}/extension/status`, {
  • Network accessline 113
    if (!response.ok) {       const fallback = await fetch(`http://127.0.0.1:${port}/extension/status`, {         signal: AbortSignal.timeout(2000),
  • Network accessline 114
    const fallback = await fetch(`http://127.0.0.1:${port}/extension/status`, {
  • Network accessline 437
    tabGroupColor?: TabGroupColor } = {}): Promise<CreatedRelaySession> {   const response = await fetch(`http://127.0.0.1:${port}/cli/session/new`, {
  • Network accessline 438
    } = {}): Promise<CreatedRelaySession> {   const response = await fetch(`http://127.0.0.1:${port}/cli/session/new`, {     method: 'POST',
  • Network accessline 439
    const response = await fetch(`http://127.0.0.1:${port}/cli/session/new`, {
  • Network accessline 465
    closeCreatedTabs?: boolean }): Promise<{ warning?: string }> {   const response = await fetch(`http://127.0.0.1:${port}/cli/session/delete`, {
  • Network accessline 466
    }): Promise<{ warning?: string }> {   const response = await fetch(`http://127.0.0.1:${port}/cli/session/delete`, {     method: 'POST',
  • Network accessline 467
    const response = await fetch(`http://127.0.0.1:${port}/cli/session/delete`, {

playwriter/src/relay-core.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 21
    const TEST_PORT = 19987 const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 22
    const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 73
    const createCliSession = async (): Promise<string> => {     const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 74
    const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 83
    const executeCli = async ({ sessionId, code, timeout }: { sessionId: string; code: string; timeout?: number }) => {     const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Network accessline 84
    const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Network accessline 92
    const deleteCliSession = async (sessionId: string): Promise<void> => {     await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 93
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 439
    arguments: {         code: js`           await state.page.goto('https://example.com');
  • Network accessline 440
    code: js           await state.page.goto('https://example.com');
  • Network accessline 441
    await state.page.goto('https://example.com');
  • Network accessline 454
    [return value] { url: 'https://example.com/', title: 'Example Domain' }",
  • Network accessline 462
    // Repro test for https://github.com/remorses/playwriter/issues/66.
  • Network accessline 484
    await newPage.route('**/api/**', async (route) => {               try {                 const response = await route.fetch();
  • Network accessline 485
    try {                 const response = await route.fetch();                 await route.fulfill({ response });
  • Network accessline 486
    const response = await route.fetch();
  • Network accessline 494
    await newPage.evaluate(async () => {               await fetch('/api/data').catch(() => null);
  • Network accessline 495
    await fetch('/api/data').catch(() => null);
  • Network accessline 533
    it('should expose cloud cookie transfer in local CLI sessions', async () => {     const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 534
    const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 541
    try {       const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Network accessline 542
    const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Access to secretsline 560
    [Credential-related source omitted]
  • Network accessline 562
    `)     } finally {       await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 563
    } finally {       await fetch(`${SERVER_URL}/cli/session/delete`, {         method: 'POST',
  • Network accessline 564
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 620
    const newPage = await context.newPage();           state.testPage = newPage;           await newPage.goto('https://example.com/mcp-test');
  • Network accessline 621
    state.testPage = newPage;           await newPage.goto('https://example.com/mcp-test');           return newPage.url();
  • Network accessline 622
    await newPage.goto('https://example.com/mcp-test');
  • Network accessline 660
    {       name: 'hacker-news',       url: 'https://news.ycombinator.com/item?id=1',
  • Network accessline 661
    name: 'hacker-news',       url: 'https://news.ycombinator.com/item?id=1',       expectedContent: ['role=link', 'Hacker News'],
  • Network accessline 662
    url: 'https://news.ycombinator.com/item?id=1',
  • Network accessline 669
    {       name: 'shadcn-ui',       url: 'https://ui.shadcn.com/',
  • Network accessline 670
    name: 'shadcn-ui',       url: 'https://ui.shadcn.com/',       expectedContent: ['shadcn'],
  • Network accessline 671
    url: 'https://ui.shadcn.com/',
  • Network accessline 922
    it('returns a structured error when the selected extension disconnected', async () => {     const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 923
    const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 1424
    const page = await browserContext.newPage()       await page.goto('https://example.com')
  • Network accessline 1425
    await page.goto('https://example.com')

playwriter/src/relay-navigation.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 309
    const page = await _browserContext.newPage()     await page.goto('https://discord.com/login', { waitUntil: 'load' })
  • Network accessline 310
    await page.goto('https://discord.com/login', { waitUntil: 'load' })
  • Network accessline 347
    const page = await browserContext.newPage()     const initialUrl = 'https://example.com/notion-repro'
  • Network accessline 348
    const initialUrl = 'https://example.com/notion-repro'
  • Network accessline 365
    const response = await cdpPage!.goto('https://www.notion.so', { waitUntil: 'domcontentloaded', timeout: 20000 })
  • Network accessline 398
    const response = await cdpPage!.goto('https://www.youtube.com', { waitUntil: 'domcontentloaded', timeout: 20000 })
  • Network accessline 460
    const page = await browserContext.newPage()     await page.goto('https://example.com')
  • Network accessline 461
    await page.goto('https://example.com')
  • Network accessline 470
    const versionRes = await fetch(`http://127.0.0.1:${TEST_PORT}/json/version`)
  • Network accessline 481
    const versionSlashRes = await fetch(`http://127.0.0.1:${TEST_PORT}/json/version/`)
  • Network accessline 485
    const listRes = await fetch(`http://127.0.0.1:${TEST_PORT}/json/list`)
  • Network accessline 501
    const jsonRes = await fetch(`http://127.0.0.1:${TEST_PORT}/json`)
  • Network accessline 507
    const putRes = await fetch(`http://127.0.0.1:${TEST_PORT}/json/version`, { method: 'PUT' })
  • Network accessline 539
    const page = await browserContext.newPage()     await page.goto(`http://localhost:${port}/a`)
  • Network accessline 540
    await page.goto(`http://localhost:${port}/a`)
  • Network accessline 560
    await cdpPage.goto(`http://127.0.0.1:${port}/b`)
  • Network accessline 595
    // Regression test for https://github.com/remorses/playwriter/issues/40
  • Network accessline 727
    // Reproduces https://github.com/remorses/playwriter/issues/18
  • Network accessline 825
    // Reproduces https://github.com/remorses/playwriter/issues/127
  • Network accessline 827
    // chrome.debugger from the whole tab at navigation start of that iframe (reason     // target_closed). The extension must reattach and replay the session setup so the     // Playwright page keeps working. https://issues.chromium.org/issues
  • Network accessline 829
    // Playwright page keeps working. https://issues.chromium.org/issues/498987209

playwriter/src/relay-session.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 56
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/?test=debugger-variables'
  • Network accessline 57
    const testUrl = 'https://example.com/?test=debugger-variables'
  • Network accessline 124
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/?test=debugger-step'
  • Network accessline 125
    const testUrl = 'https://example.com/?test=debugger-step'
  • Network accessline 272
    const bpId = await dbg.setBreakpoint({ file: 'https://example.com/test.js', line: 1 })
  • Network accessline 275
    expect(dbg.listBreakpoints()[0]).toMatchObject({       id: bpId,       file: 'https://example.com/test.js',
  • Network accessline 276
    id: bpId,       file: 'https://example.com/test.js',       line: 1,
  • Network accessline 277
    file: 'https://example.com/test.js',
  • Network accessline 292
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 293
    await page.goto('https://example.com/')
  • Network accessline 361
    const page = await browserContext.newPage()     const testUrl = 'https://example.com/?test=debugger-profiler'
  • Network accessline 362
    const testUrl = 'https://example.com/?test=debugger-profiler'
  • Network accessline 416
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 417
    await page.goto('https://example.com/')
  • Network accessline 435
    const initialTargets = await cdpSession.send('Target.getTargets')     const initialPageTarget = initialTargets.targetInfos.find((t) => t.type === 'page' && t.url.includes('example.com'))     expect(initialPageTarget?.url).toBe('https://exam
  • Network accessline 437
    expect(initialPageTarget?.url).toBe('https://example.com/')
  • Network accessline 439
    await cdpPage!.goto('https://example.org/', { waitUntil: 'domcontentloaded' })
  • Network accessline 467
    const page = await browserContext.newPage()     await page.goto('https://example.com/?test=shared-evaluate')
  • Network accessline 468
    await page.goto('https://example.com/?test=shared-evaluate')
  • Network accessline 511
    const page1 = await browserContext.newPage()     await page1.goto('https://example.com/')
  • Network accessline 512
    await page1.goto('https://example.com/')
  • Network accessline 518
    const page2 = await browserContext.newPage()     await page2.goto('https://example.org/')
  • Network accessline 519
    await page2.goto('https://example.org/')
  • Network accessline 549
    {               "type": "page",               "url": "https://example.com/",
  • Network accessline 550
    "type": "page",               "url": "https://example.com/",             },
  • Network accessline 551
    "url": "https://example.com/",
  • Network accessline 553
    {               "type": "page",               "url": "https://example.org/",
  • Network accessline 554
    "type": "page",               "url": "https://example.org/",             },
  • Network accessline 555
    "url": "https://example.org/",
  • Network accessline 574
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 575
    await page.goto('https://example.com/')
  • Network accessline 584
    .pages()       .find((candidatePage) => {         return candidatePage.url() === 'https://example.com/'
  • Network accessline 585
    .find((candidatePage) => {         return candidatePage.url() === 'https://example.com/'       })
  • Network accessline 586
    return candidatePage.url() === 'https://example.com/'
  • Network accessline 604
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 605
    await page.goto('https://example.com/')
  • Network accessline 613
    await page.goto('https://example.org/', { waitUntil: 'domcontentloaded' })
  • Network accessline 641
    const page = await browserContext.newPage()     const initialUrl = 'https://example.com/'
  • Network accessline 642
    const initialUrl = 'https://example.com/'
  • Network accessline 667
    const newUrl = 'https://example.org/'
  • Network accessline 697
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 698
    await page.goto('https://example.com/')
  • Network accessline 846
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 847
    await page.goto('https://example.com/')
  • Network accessline 896
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 897
    await page.goto('https://example.com/')
  • Network accessline 966
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 967
    await page.goto('https://example.com/')
  • Network accessline 1047
    <html>             <head>                 <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  • Network accessline 1048
    <head>                 <script src="https://unpkg.com/react@18/umd/react.development.js"></script>                 <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  • Network accessline 1049
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  • Network accessline 1050
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  • Network accessline 1170
    const page = await browserContext.newPage()     await page.goto('https://web.dev/', { waitUntil: 'load' })
  • Network accessline 1171
    await page.goto('https://web.dev/', { waitUntil: 'load' })
  • Network accessline 1205
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 1206
    await page.goto('https://example.com/')
  • Network accessline 1230
    const [response] = await Promise.all([       cdpPage!.waitForResponse((resp) => resp.url() === 'https://example.com/'),
  • Network accessline 1231
    cdpPage!.waitForResponse((resp) => resp.url() === 'https://example.com/'),
  • Network accessline 1232
    cdpPage!.goto('https://example.com/'),

playwriter/src/relay-state.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 28
    type: 'page',     title: 'Test Page',     url: 'https://example.com',
  • Network accessline 29
    title: 'Test Page',     url: 'https://example.com',     attached: true,
  • Network accessline 30
    url: 'https://example.com',
  • Network accessline 409
    sessionId: 'pw-tab-1',       targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://updated.com' }),
  • Network accessline 410
    targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://updated.com' }),     })
  • Network accessline 411
    targetInfo: makeTargetInfo({ url: 'https://updated.com' }),
  • Network accessline 414
    const target = state.extensions.get('ext-1')!.connectedTargets.get('pw-tab-1')!     expect(target.targetInfo.url).toBe('https://updated.com')
  • Network accessline 415
    expect(target.targetInfo.url).toBe('https://updated.com')
  • Network accessline 552
    sessionId: 'pw-tab-1',       targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://old.com', title: 'Old' }),
  • Network accessline 553
    targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://old.com', title: 'Old' }),     })
  • Network accessline 554
    targetInfo: makeTargetInfo({ url: 'https://old.com', title: 'Old' }),
  • Network accessline 558
    extensionId: 'ext-1',       sessionId: 'pw-tab-1',       url: 'https://new.com',
  • Network accessline 559
    sessionId: 'pw-tab-1',       url: 'https://new.com',       title: 'New Page',
  • Network accessline 560
    url: 'https://new.com',
  • Network accessline 564
    const target = after.extensions.get('ext-1')!.connectedTargets.get('pw-tab-1')!     expect(target.targetInfo.url).toBe('https://new.com')
  • Network accessline 565
    expect(target.targetInfo.url).toBe('https://new.com')
  • Network accessline 573
    sessionId: 'pw-tab-1',       targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://example.com', title: 'Keep This' }),
  • Network accessline 574
    targetId: 'target-1',       targetInfo: makeTargetInfo({ url: 'https://example.com', title: 'Keep This' }),     })
  • Network accessline 575
    targetInfo: makeTargetInfo({ url: 'https://example.com', title: 'Keep This' }),
  • Network accessline 579
    extensionId: 'ext-1',       sessionId: 'pw-tab-1',       url: 'https://example.com/new-path',
  • Network accessline 580
    sessionId: 'pw-tab-1',       url: 'https://example.com/new-path',     })
  • Network accessline 581
    url: 'https://example.com/new-path',
  • Network accessline 584
    const target = after.extensions.get('ext-1')!.connectedTargets.get('pw-tab-1')!     expect(target.targetInfo.url).toBe('https://example.com/new-path')
  • Network accessline 585
    expect(target.targetInfo.url).toBe('https://example.com/new-path')
  • Network accessline 592
    extensionId: 'ext-1',       sessionId: 'pw-tab-nope',       url: 'https://example.com',
  • Network accessline 593
    sessionId: 'pw-tab-nope',       url: 'https://example.com',     })
  • Network accessline 594
    url: 'https://example.com',

playwriter/src/relay-state.ts

  • Executable scriptline 1
    Executable file

playwriter/src/remote-control.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 24
    export const REMOTE_TUNNEL_BASE_DOMAIN = 'playwriter.dev' export const REMOTE_VIEWER_BASE_URL = 'https://playwriter.dev'
  • Network accessline 25
    export const REMOTE_VIEWER_BASE_URL = 'https://playwriter.dev'
  • Network accessline 123
    baseDomain?: string }): string {   return `https://${baseDomain}`
  • Network accessline 124
    }): string {   return `https://${baseDomain}` }
  • Network accessline 125
    return `https://${baseDomain}`
  • Network accessline 409
    Then use the printed session id. Read https://playwriter.dev/SKILL.md. NEVER share this id.

playwriter/src/remote-control.unit.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 41
    test('the shared link points at the viewer page and hides the id in the hash', () => {     const url = buildRemoteControlUrl({ tunnelId: 'abc123' })     expect(url).toMatchInlineSnapshot(`"https://playwriter.dev/remote-control#abc123"`)
  • Network accessline 43
    expect(url).toMatchInlineSnapshot(`"https://playwriter.dev/remote-control#abc123"`)
  • Network accessline 63
    `"wss://playwriter.dev/tunnel/abc123/upstream"`,     )     expect(buildTunnelOrigin({})).toMatchInlineSnapshot(`"https://playwriter.dev"`)
  • Network accessline 65
    expect(buildTunnelOrigin({})).toMatchInlineSnapshot(`"https://playwriter.dev"`)
  • Network accessline 77
    test('still accepts a tunnel host verbatim, including older and self-hosted domains', () => {     expect(parseRemoteControlUrl('https://abc123-tunnel.traforo.dev')).toMatchInlineSnapshot(`
  • Network accessline 78
    expect(parseRemoteControlUrl('https://abc123-tunnel.traforo.dev')).toMatchInlineSnapshot(`
  • Network accessline 89
    expect(parseRemoteControlUrl('https://abc123-tunnel.mycompany.com').wsUrl).toBe(
  • Network accessline 94
    test('explains the unquoted-shell case when the hash is missing', () => {     expect(() =>       parseRemoteControlUrl('https://playwriter.dev/remote-control'),
  • Network accessline 95
    expect(() =>       parseRemoteControlUrl('https://playwriter.dev/remote-control'),     ).toThrowErrorMatchingInlineSnapshot(`
  • Network accessline 96
    parseRemoteControlUrl('https://playwriter.dev/remote-control'),
  • Network accessline 99
    playwriter session new --remote your-id]     `)     expect(extractViewerTunnelId('https://playwriter.dev/remote-control#BAD_ID')).toBe(null)
  • Network accessline 100
    `)     expect(extractViewerTunnelId('https://playwriter.dev/remote-control#BAD_ID')).toBe(null)     expect(extractViewerTunnelId('https://playwriter.dev/other#abc123')).toBe(null)
  • Network accessline 101
    expect(extractViewerTunnelId('https://playwriter.dev/remote-control#BAD_ID')).toBe(null)
  • Network accessline 102
    expect(extractViewerTunnelId('https://playwriter.dev/other#abc123')).toBe(null)
  • Network accessline 211
    Then use the printed session id. Read https://playwriter.dev/SKILL.md. NEVER share this id."
  • Network accessline 268
    test('finds the announced tab session in the pushed attach event', () => {     const attached = decodeExtensionCdpMessage(       '{"method":"forwardCDPEvent","params":{"method":"Target.attachedToTarget","params":{"sessionId":"pw-tab-7-1","t
  • Network accessline 269
    const attached = decodeExtensionCdpMessage(       '{"method":"forwardCDPEvent","params":{"method":"Target.attachedToTarget","params":{"sessionId":"pw-tab-7-1","targetInfo":{"url":"https://example.com","type":"page"}}}}',     )
  • Network accessline 270
    '{"method":"forwardCDPEvent","params":{"method":"Target.attachedToTarget","params":{"sessionId":"pw-tab-7-1","targetInfo":{"url":"https://example.com","type":"page"}}}}',
  • Network accessline 273
    {         "sessionId": "pw-tab-7-1",         "url": "https://example.com",
  • Network accessline 274
    "sessionId": "pw-tab-7-1",         "url": "https://example.com",       }
  • Network accessline 275
    "url": "https://example.com",

playwriter/src/resource.md

  • Access to secretsline 33
    [Credential-related source omitted]
  • Network accessline 75
    await state.page.goto('https://example.com')
  • Network accessline 76
    // Wait for page load (smart detection that ignores analytics/ads) await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' }) await waitForPageLoad({ page: state.page })
  • Network accessline 77
    await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' })

playwriter/src/scoped-fs.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/scoped-fs.ts

  • Executable scriptline 1
    Executable file
  • Dangerous shell operationline 264
    rm = (filePath: any, ...args: any[]): void => {

playwriter/src/screen-recording.test.ts

  • Executable scriptline 1
    Executable file

playwriter/src/screen-recording.ts

  • Executable scriptline 1
    Executable file

playwriter/src/screencast-background-tab.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 35
    }           const tabAId = tabA.id           await c.tabs.update(tabAId, { url: 'https://example.com' })
  • Network accessline 36
    const tabAId = tabA.id           await c.tabs.update(tabAId, { url: 'https://example.com' })           await sleep(2500)
  • Network accessline 37
    await c.tabs.update(tabAId, { url: 'https://example.com' })
  • Network accessline 38
    await sleep(2500)           const tabB = await c.tabs.create({ url: 'https://example.com', active: false })           if (tabB.id === undefined) {
  • Network accessline 39
    const tabB = await c.tabs.create({ url: 'https://example.com', active: false })

playwriter/src/skill.md

  • Network accessline 58
    Node programs and TypeScript SDKs use the `playwriter` package as a library. Do not POST `/cli/session/new` yourself. Docs: https://playwriter.dev/docs/sessions#node-api
  • Network accessline 65
    // page: closes the tab this script opened await using page = await connection.browser.contexts()[0].newPage() await page.goto('https://example.com')
  • Network accessline 67
    await page.goto('https://example.com')
  • Network accessline 70
    **Always** close the tabs your script opens (`await using page` or `page.close()`). A tab you leave open stays in Chrome, so a later process can reuse it via `context.pages()`. Match the tab by its **exact** url (`p.url() === 'https://examp
  • Network accessline 72
    To share one tab between processes (for example many SDK scripts calling `fetch` inside a signed-in site), keep the holder list inside the tab (`window.__shared`, updated with one atomic `page.evaluate`), and let the last holder call `page.
  • Network accessline 78
    Playwriter can control a Chrome browser running on a different machine over the internet. The host machine runs `playwriter serve` with a [traforo](https://traforo.dev) tunnel, and the remote machine connects through the tunnel URL.
  • Network accessline 86
    [Credential-related source omitted]
  • Access to secretsline 86
    [Credential-related source omitted]
  • Network accessline 88
    playwriter -s 1 -e "state.page = await context.newPage(); await state.page.goto('https://example.com')"
  • Network accessline 91
    For the full guide (Docker, LAN, MCP config, security), see: https://playwriter.dev/docs/remote-access
  • Network accessline 121
    # Then use the session normally playwriter -s 1 -e "state.page = await context.newPage(); await state.page.goto('https://example.com')"
  • Network accessline 122
    playwriter -s 1 -e "state.page = await context.newPage(); await state.page.goto('https://example.com')"
  • Network accessline 182
    # Use the session normally playwriter -s 1 -e "state.page = await context.newPage(); await state.page.goto('https://example.com')"
  • Network accessline 183
    playwriter -s 1 -e "state.page = await context.newPage(); await state.page.goto('https://example.com')"
  • Access to secretsline 202
    [Credential-related source omitted]
  • Network accessline 210
    # Option 2: API key (for CI, VPS, headless — no browser needed) # Create one at https://playwriter.dev/dashboard, then:
  • Network accessline 211
    # Create one at https://playwriter.dev/dashboard, then:
  • Access to secretsline 212
    [Credential-related source omitted]
  • Network accessline 258
    for (const url of urls) {   if (signal.aborted) break   state.results.push(await (await fetch(url, { signal })).text())
  • Network accessline 259
    if (signal.aborted) break   state.results.push(await (await fetch(url, { signal })).text()) }
  • Network accessline 260
    state.results.push(await (await fetch(url, { signal })).text())
  • Network accessline 277
    # Navigate to a page playwriter -s 1 -e 'state.page = await context.newPage(); await state.page.goto("https://example.com")'
  • Network accessline 278
    playwriter -s 1 -e 'state.page = await context.newPage(); await state.page.goto("https://example.com")'
  • Network accessline 360
    Niche use case: `playwriter stream start|stop|status` streams `state.page` live to RTMP endpoints via CDP screencast and ffmpeg (must be on PATH). It survives navigation and CLI exit, and ends when the page closes or the session is reset. D
  • Access to secretsline 429
    [Credential-related source omitted]
  • Access to secretsline 437
    [Credential-related source omitted]
  • Access to secretsline 439
    [Credential-related source omitted]
  • Network accessline 457
    from: state.page,   to: 'cloud-1',   urls: ['https://example.com', 'https://api.example.com'],
  • Network accessline 458
    to: 'cloud-1',   urls: ['https://example.com', 'https://api.example.com'], })
  • Network accessline 459
    urls: ['https://example.com', 'https://api.example.com'],
  • Access to secretsline 463
    [Credential-related source omitted]
  • Access to secretsline 465
    [Credential-related source omitted]
  • Network accessline 545
    // Step 1: navigate + observe state.page = await context.newPage() await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' })
  • Network accessline 546
    state.page = await context.newPage() await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' }) console.log('URL:', state.page.url())
  • Network accessline 547
    await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' })
  • Network accessline 653
    await state.page.goto('https://example.com')
  • Network accessline 664
    state.page = await context.newPage() await state.page.goto('https://www.instagram.com/p/ABC123/', { waitUntil: 'domcontentloaded' })
  • Network accessline 665
    await state.page.goto('https://www.instagram.com/p/ABC123/', { waitUntil: 'domcontentloaded' })
  • Network accessline 739
    URL: https://example.com/
  • Network accessline 831
    state.page = await context.newPage() await state.page.goto('https://example.com')
  • Network accessline 832
    await state.page.goto('https://example.com')
  • Network accessline 849
    if (!state.page || state.page.isClosed()) state.page = await context.newPage() await state.page.goto('https://example.com')
  • Network accessline 850
    await state.page.goto('https://example.com')
  • Network accessline 868
    await state.page.goto('https://example.com', { waitUntil: 'domcontentloaded' })
  • Network accessline 877
    const data = await state.page.evaluate(async (url) => {   const resp = await fetch(url)
  • Network accessline 878
    const resp = await fetch(url)
  • Network accessline 880
    }, 'https://example.com/protected/resource')
  • Network accessline 898
    const cdp = await getCDPSession({ page: state.page }) const { cookies } = await cdp.send('Network.getCookies', {   urls: ['https://example.com', 'https://www.example.com'],
  • Network accessline 899
    const { cookies } = await cdp.send('Network.getCookies', {   urls: ['https://example.com', 'https://www.example.com'], })
  • Network accessline 900
    urls: ['https://example.com', 'https://www.example.com'],
  • Network accessline 910
    // Fetch protected data and trigger download to user's Downloads folder await state.page.evaluate(async (url) => {   const resp = await fetch(url)
  • Network accessline 911
    await state.page.evaluate(async (url) => {   const resp = await fetch(url)   const data = await resp.text()
  • Network accessline 912
    const resp = await fetch(url)
  • Network accessline 917
    a.download = 'data.json'   a.click() }, 'https://example.com/protected/large-file')
  • Network accessline 918
    a.click() }, 'https://example.com/protected/large-file') // File saves to ~/Downloads - read it from there
  • Network accessline 919
    }, 'https://example.com/protected/large-file')
  • Network accessline 992
    // Download a specific image to disk const fs = require('node:fs') const resp = await fetch(images[0].src)
  • Network accessline 993
    const fs = require('node:fs') const resp = await fetch(images[0].src) const buf = Buffer.from(await resp.arrayBuffer())
  • Network accessline 994
    const resp = await fetch(images[0].src)
  • Network accessline 1135
    await inspectPinnedElement('https://example.com', 'globalThis.playwriterPinnedElem1')
  • Network accessline 1138
    **getStylesForLocator** - inspect CSS styles applied to an element, like browser DevTools "Styles" panel. Useful for debugging styling issues, finding where a CSS property is defined (file:line), and checking inherited styles. Returns selec
  • Network accessline 1148
    **createDebugger** - set breakpoints, step through code, inspect variables at runtime. Useful for debugging issues that only reproduce in browser, understanding code flow, and inspecting state at specific points. Can pause on exceptions, ev
  • Network accessline 1159
    **createEditor** - view and live-edit page scripts and CSS at runtime. Edits are in-memory (persist until reload). Useful for testing quick fixes, searching page scripts with grep, and toggling debug flags. ALWAYS read `https://playwriter.d
  • Network accessline 1310
    state.responses = [] state.page.on('request', (req) => {   if (req.url().includes('/api/')) state.requests.push({ url: req.url(), method: req.method(), headers: req.headers() })
  • Network accessline 1311
    state.page.on('request', (req) => {   if (req.url().includes('/api/')) state.requests.push({ url: req.url(), method: req.method(), headers: req.headers() }) })
  • Network accessline 1312
    if (req.url().includes('/api/')) state.requests.push({ url: req.url(), method: req.method(), headers: req.headers() })
  • Network accessline 1340
    const { url, headers } = state.requests.find((r) => r.url.includes('feed'))
  • Network accessline 1341
    const data = await state.page.evaluate(   async ({ url, headers }) => {     const res = await fetch(url, { headers })
  • Network accessline 1342
    async ({ url, headers }) => {     const res = await fetch(url, { headers })     return res.json()
  • Network accessline 1343
    const res = await fetch(url, { headers })
  • Network accessline 1453
    When running in [Ghost Browser](https://ghostbrowser.com/), the `chrome` object exposes APIs for multi-identity automation (identities, proxies, sessions). See `extension/src/ghost-browser-api.d.ts` for full API reference. Only works in Gho

playwriter/src/snapshot-tools.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 47
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 48
    await page.goto('https://example.com/')
  • Network accessline 153
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 154
    await page.goto('https://example.com/')
  • Dangerous shell operationline 314
    const locatorFromString = eval('testPage.' + locatorString);
  • Network accessline 519
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 520
    await page.goto('https://example.com/')
  • Network accessline 602
    const page = await browserContext.newPage()     await page.goto('https://example.com/')
  • Network accessline 603
    await page.goto('https://example.com/')
  • Network accessline 764
    const testPages = [       { name: 'old-reddit', url: 'https://old.reddit.com/' },
  • Network accessline 765
    { name: 'old-reddit', url: 'https://old.reddit.com/' },
  • Network accessline 766
    { name: 'hacker-news', url: 'https://news.ycombinator.com/' },

playwriter/src/start-relay-server.ts

  • Executable scriptline 1
    Executable file
  • Access to secretsline 69
    [Credential-related source omitted]

playwriter/src/styles-examples.ts

  • Executable scriptline 1
    Executable file

playwriter/src/styles.ts

  • Executable scriptline 1
    Executable file

playwriter/src/tab-groups.test.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 18
    const TEST_PORT = 19972 const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 19
    const SERVER_URL = `http://127.0.0.1:${TEST_PORT}`
  • Network accessline 36
    const executeCli = async ({ sessionId, code }: { sessionId: string; code: string }) => {     const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Network accessline 37
    const response = await fetch(`${SERVER_URL}/cli/execute`, {
  • Network accessline 72
    it('puts session tabs in a custom group while toggled tabs stay in the default one', async () => {     const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 73
    const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 117
    it('renames the session group via /cli/session/update and keeps it for new tabs', async () => {     const listResponse = await fetch(`${SERVER_URL}/cli/sessions`)
  • Network accessline 118
    const listResponse = await fetch(`${SERVER_URL}/cli/sessions`)
  • Network accessline 123
    const updateResponse = await fetch(`${SERVER_URL}/cli/session/update`, {
  • Network accessline 162
    const finalList = await fetch(`${SERVER_URL}/cli/sessions`)
  • Network accessline 174
    `,     })     await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 175
    })     await fetch(`${SERVER_URL}/cli/session/delete`, {       method: 'POST',
  • Network accessline 176
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 186
    const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 207
    const updateResponse = await fetch(`${SERVER_URL}/cli/session/update`, {
  • Network accessline 229
    `,     })     await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 230
    })     await fetch(`${SERVER_URL}/cli/session/delete`, {       method: 'POST',
  • Network accessline 231
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 238
    it('supports an explicit tab group color on creation and color-only updates', async () => {     const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 239
    const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 264
    const updateResponse = await fetch(`${SERVER_URL}/cli/session/update`, {
  • Network accessline 290
    `,     })     await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 291
    })     await fetch(`${SERVER_URL}/cli/session/delete`, {       method: 'POST',
  • Network accessline 292
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 301
    const createResponse = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 322
    const updateResponse = await fetch(`${SERVER_URL}/cli/session/update`, {
  • Network accessline 345
    `,     })     await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 346
    })     await fetch(`${SERVER_URL}/cli/session/delete`, {       method: 'POST',
  • Network accessline 347
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 354
    it('a session without --tab-group uses the default group, not an existing custom one', async () => {     const newSession = async (body: { tabGroup?: string }) => {       const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 355
    const newSession = async (body: { tabGroup?: string }) => {       const response = await fetch(`${SERVER_URL}/cli/session/new`, {         method: 'POST',
  • Network accessline 356
    const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 403
    for (const sessionId of [custom, plain]) {       await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 404
    await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 412
    it('deleting a session with closeCreatedTabs closes only its own tabs, not same-group tabs of other sessions', async () => {     const newSession = async () => {       const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 413
    const newSession = async () => {       const response = await fetch(`${SERVER_URL}/cli/session/new`, {         method: 'POST',
  • Network accessline 414
    const response = await fetch(`${SERVER_URL}/cli/session/new`, {
  • Network accessline 442
    const staleResponse = await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 449
    const deleteResponse = await fetch(`${SERVER_URL}/cli/session/delete`, {
  • Network accessline 467
    await fetch(`${SERVER_URL}/cli/session/delete`, {

playwriter/src/telemetry.ts

  • Network accessline 1
    /**  * Anonymous usage telemetry sent to Strada (https://strada.sh).
  • Executable scriptline 1
    Executable file
  • Network accessline 2
    * Anonymous usage telemetry sent to Strada (https://strada.sh).

playwriter/src/test-declarations.ts

  • Executable scriptline 1
    Executable file

playwriter/src/test-utils.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 265
    return {     baseUrl: `http://127.0.0.1:${address.port}`,
  • Network accessline 266
    baseUrl: `http://127.0.0.1:${address.port}`,
  • Network accessline 406
    return {     baseUrl: `http://127.0.0.1:${address.port}`,
  • Network accessline 407
    baseUrl: `http://127.0.0.1:${address.port}`,     close: async () => {       for (const socket of openSockets) {

playwriter/src/utils.ts

  • Executable scriptline 1
    Executable file
  • Network accessline 30
    *  * Examples:  *   "192.168.1.10"                        → http://192.168.1.10:19988, ws://192.168.1.10:19988
  • Network accessline 31
    * Examples:  *   "192.168.1.10"                        → http://192.168.1.10:19988, ws://192.168.1.10:19988  *   "https://my-machine-tunnel.traforo.dev" → https://my-machine-tunnel.traforo.dev, wss://my-machine-tunnel.traforo.dev
  • Network accessline 32
    *   "192.168.1.10"                        → http://192.168.1.10:19988, ws://192.168.1.10:19988
  • Network accessline 33
    *   "https://my-machine-tunnel.traforo.dev" → https://my-machine-tunnel.traforo.dev, wss://my-machine-tunnel.traforo.dev
  • Network accessline 42
    }   return {     httpBaseUrl: `http://${host}:${port}`,
  • Network accessline 43
    return {     httpBaseUrl: `http://${host}:${port}`,     wsBaseUrl: `ws://${host}:${port}`,
  • Network accessline 44
    httpBaseUrl: `http://${host}:${port}`,

playwriter/src/wait-for-page-load.ts

  • Executable scriptline 1
    Executable file

skills/playwriter/SKILL.md

  • Network accessline 29
    playwriter session new playwriter -s 1 -e 'state.page = await context.newPage(); await state.page.goto("https://example.com")'
  • Network accessline 30
    playwriter -s 1 -e 'state.page = await context.newPage(); await state.page.goto("https://example.com")'

How the signals fit together

Facts from a static read of the files at the pinned commit. They describe what the code does, not why.

Some files could not be read; the facts below still hold.

Declared and executed: 4 facts
Signal confidence: 496 facts

and 446 more

Only the first 500 facts are listed.

Works with

Agent compatibility, from the files in this repository
AgentStatusEvidenceInstall to
Claude CodeCompatibleStandard SKILL.md skills/playwriter/SKILL.md.claude/skills/<skill-name>/
CodexNativeManifest AGENTS.md.agents/skills/<skill-name>/
CursorCompatibleStandard SKILL.md skills/playwriter/SKILL.md.cursor/skills/<skill-name>/
Gemini CLICompatibleStandard SKILL.md skills/playwriter/SKILL.md.gemini/skills/<skill-name>/
GitHub CopilotCompatibleStandard SKILL.md skills/playwriter/SKILL.md.github/skills/<skill-name>/
OpenCodeCompatibleStandard SKILL.md skills/playwriter/SKILL.md.opencode/skills/<skill-name>/
  • Native The repository ships a manifest, folder or frontmatter field for this agent.
  • Compatible A standard SKILL.md that this agent can read.
  • Unknown No evidence either way.

Derived automatically from paths, manifests and frontmatter. Not tested on each agent.

Add this badge to your README

It updates every night and links to this page.

remorses/playwriter: #311 on hotskills, 4.1k stars

[![remorses/playwriter on hotskills](https://hotskills.dev/badge/remorses-playwriter.svg)](https://hotskills.dev/skill/remorses-playwriter/)