-
-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Attempt to make Playwright run with Firefox
- Loading branch information
1 parent
af4ac78
commit 7a9bcf4
Showing
5 changed files
with
244 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import {test as base, firefox, type BrowserContext} from '@playwright/test' | ||
import {loadFirefoxAddon} from './messaging-client' | ||
|
||
export const extensionFixturesFirefox = ( | ||
pathToExtension: string, | ||
headless: boolean | ||
) => { | ||
return base.extend<{ | ||
context: BrowserContext | ||
extensionId: string | ||
}>({ | ||
context: async ({}, use) => { | ||
// Connect with the Extension.js remote desktop client | ||
const RDP_PORT = 9222 | ||
|
||
// Override or add custom preferences here if needed | ||
const masterPreferences = {} | ||
|
||
// Create a temporary profile path for Firefox | ||
const firefoxProfilePath = '' | ||
|
||
const context = await firefox.launchPersistentContext( | ||
firefoxProfilePath, | ||
{ | ||
headless: headless, | ||
args: [`-start-debugger-server=${String(RDP_PORT)}`].filter( | ||
(arg) => !!arg | ||
), | ||
firefoxUserPrefs: { | ||
...masterPreferences, | ||
'devtools.debugger.remote-enabled': true, | ||
'devtools.debugger.prompt-connection': false | ||
} | ||
} | ||
) | ||
|
||
|
||
// Use the context in the test | ||
await use(context) | ||
|
||
// Await the addon loading to ensure it's complete before proceeding | ||
await loadFirefoxAddon(RDP_PORT, '127.0.0.1', pathToExtension) | ||
|
||
// Close the context after the test | ||
// await context.close() | ||
}, | ||
extensionId: async ({context}, use) => { | ||
// For manifest v2: | ||
let [background] = context.backgroundPages() | ||
if (!background) background = await context.waitForEvent('backgroundpage') | ||
|
||
const extensionId = background.url().split('/')[2] | ||
await use(extensionId) | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import {Buffer} from 'buffer' | ||
import net from 'net' | ||
|
||
export const loadFirefoxAddon = ( | ||
port: number, | ||
host: string, | ||
addonPath: string | ||
) => { | ||
return new Promise<boolean>((resolve) => { | ||
const socket = net.connect({ | ||
port, | ||
host | ||
}) | ||
|
||
let success = false | ||
|
||
socket.once('error', () => {}) | ||
socket.once('close', () => { | ||
resolve(success) | ||
}) | ||
|
||
const send = (data: Record<string, string>) => { | ||
const raw = Buffer.from(JSON.stringify(data)) | ||
|
||
socket.write(`${raw.length}`) | ||
socket.write(':') | ||
socket.write(raw) | ||
} | ||
|
||
send({ | ||
to: 'root', | ||
type: 'getRoot' | ||
}) | ||
|
||
const onMessage = (message: any) => { | ||
if (message.addonsActor) { | ||
send({ | ||
to: message.addonsActor, | ||
type: 'installTemporaryAddon', | ||
addonPath | ||
}) | ||
} | ||
|
||
if (message.addon) { | ||
success = true | ||
socket.end() | ||
} | ||
|
||
if (message.error) { | ||
socket.end() | ||
} | ||
} | ||
|
||
const buffers: Buffer[] = [] | ||
// let remainingBytes = 0 | ||
|
||
socket.on('data', (data) => { | ||
buffers.push(data) | ||
|
||
const buffer = Buffer.concat(buffers) | ||
const colonIndex = buffer.indexOf(':') | ||
|
||
if (colonIndex === -1) return | ||
|
||
const expectedLength = parseInt( | ||
buffer.subarray(0, colonIndex).toString(), | ||
10 | ||
) | ||
|
||
if (!Number.isFinite(expectedLength)) { | ||
throw new Error('Invalid message size') | ||
} | ||
|
||
const remainingData = buffer.subarray(colonIndex + 1) | ||
if (remainingData.length >= expectedLength) { | ||
const message = remainingData.subarray(0, expectedLength).toString() | ||
buffers.length = 0 // Clear buffer after processing | ||
|
||
try { | ||
const json = JSON.parse(message) | ||
onMessage(json) | ||
} catch (error) { | ||
console.error('Error parsing JSON:', error) | ||
} | ||
} | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters