playwright
playwright copied to clipboard
[Feature] Support running extensions with Firefox
Context:
- Playwright Version: 1.9.0
- Operating System: Linux 5.4 Ubuntu 20.04.2 LTS (Focal Fossa)
- Node.js version: 14.17.1
- Browser: Firefox
Can't connect to the Firefox browser using this code: https://github.com/microsoft/playwright/issues/2644#issuecomment-647842059
The code freezes on the:
const browser = await firefox.connect({ wsEndpoint });
I see the browser with extension started, but Playwright can't connect to Firefox.
Can't connect to the Firefox browser using this code: #2644 (comment)
@Pooort Well, this was a best-effort hack that didn't age well. So overall, that's not a bug: it was never officially supported.
We probably can support it properly, but that's an engineering effort. The more upvotes this issue gets, the higher we'll prioritize it!
@aslushnikov I appreciate your effort. It would be nice to have extensions support. Voting up.
agreed. this would be fantastic.
This is definitely a much needed feature. Recently I was exploring to use Playwright and which going creating POC, I can to know through different github issues that Playwright always launch in incognito mode and there is not such easy way to launch a normal browser(https://github.com/microsoft/playwright/issues/2071). Incognito mode is not great with testing extensions.
It would be great if there is easy support for extension across all browsers since its one of the USP of Playwright.
It would be nice to have extensions support. Voting up.
Hi, It will be great to have firefox extension support. Voting up.
@aslushnikov are there any plans to make it works?
I would also like to see this feature integrated.
Being able to test a website with multiple browsers and commonly used extensions all with the same code will be a real game changer.
I found another workaround to install add-ons to Firefox. Firefox allows installing addons via RDP (Remote Debugging Protocol). The following shows how to install addons by the RDP client implemented in web-ext
.
import { firefox } from 'playwright';
// 'remote' is not defined by "exports" in package.json
import { connect } from './node_modules/web-ext/lib/firefox/remote.js';
const RDP_PORT = 12345;
(async () => {
const browser = await firefox.launch({
headless: false,
args: [ '-start-debugger-server', String(RDP_PORT) ],
firefoxUserPrefs: {
'devtools.debugger.remote-enabled': true,
'devtools.debugger.prompt-connection': false,
}
});
const client = await connect(RDP_PORT);
const resp = await client.installTemporaryAddon("path/to/addon/directory");
console.log("Installed addon with ID", resp.addon.id);
const page = await browser.newPage();
await page.goto('https://mozilla.org');
// ...
})();
Although this example imports an internal module, I believe it's better to use another client, such as Foxdriver (or implement a client yourself).
@ueokande Here's a full native Node.js implementation of this - no need to use web-ext
or any external client:
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) => {
while (true) {
if (remainingBytes === 0) {
const index = data.indexOf(':');
buffers.push(data);
if (index === -1) {
return;
}
const buffer = Buffer.concat(buffers);
const bufferIndex = buffer.indexOf(':');
buffers.length = 0;
remainingBytes = Number(buffer.subarray(0, bufferIndex).toString());
if (!Number.isFinite(remainingBytes)) {
throw new Error('Invalid state');
}
data = buffer.subarray(bufferIndex + 1);
}
if (data.length < remainingBytes) {
remainingBytes -= data.length;
buffers.push(data);
break;
} else {
buffers.push(data.subarray(0, remainingBytes));
const buffer = Buffer.concat(buffers);
buffers.length = 0;
const json = JSON.parse(buffer.toString());
queueMicrotask(() => {
onMessage(json);
});
const remainder = data.subarray(remainingBytes);
remainingBytes = 0;
if (remainder.length === 0) {
break;
} else {
data = remainder;
}
}
}
});
});
};
Hello All ,
I have tried the below code in java to launch extension , its working but its getting launged in nightly . Is this still a limitation or something wrong with the code . Can some one help me here pls ?
Playwright playwright = Playwright.create() Path extpath=Paths get("profile\extension)
List<String> Args= new ArrayList<>();
Args.add("--dusable-extension-except="+extpath); Args.add("--load-extension="+ extpath)
BrowserType.LaunchPersistentContextOptions lp= new BrowserType.LaunchPersistentContextOptions(); lp.setChannel("firefox") lp.setHeadless(false) lp.args=Args lp.setDevtools(false) Path path= Paths.get(path to profile folder) BrowserContext browser= playwright.firefox().launchPersistentContext(path, lp) Page page= browser.pages().get(0) page.navigate() ....
The above cose is working with extensionbut its loading in Nightly .. is it a limitation or something wrong with code ?
add pls.
add pls (python)
Hi! I have published npm package which enables you to load an extensions on playwright. https://github.com/ueokande/playwright-webextext
@ueokande I used your package to install the addon. The addon installed successfully but it is asking for permissions and I am not able to give permissions to it. is there any way to do this ?
Much needed! (java)
@ueokande nice work getting extension to load 👍
to playwright team:
however, page actions (goto, click, etc...) on moz-extension://
pages will not work until firefox patches are updated
e.g.
https://github.com/microsoft/playwright/blob/1277ec99008898cba23c3511d024972e42409963/browser_patches/firefox/juggler/content/JugglerFrameChild.jsm#L41-L43
some things work
e.g.
await page.waitForLoadState('networkidle');
pw:channel:command {
pw:channel:command id: 6,
pw:channel:command guid: 'frame@44f2c0a9f446a32cee5a435dd16eca6c',
pw:channel:command method: 'goto',
pw:channel:command params: {
pw:channel:command url: 'moz-extension://hardcoded-nordvpn-extension-id/index.html',
pw:channel:command waitUntil: 'networkidle'
pw:channel:command }
pw:channel:command } +215ms
pw:channel:event {
pw:channel:event guid: 'frame@cc52296d171fadaeb877b44318785291',
pw:channel:event method: 'loadstate',
pw:channel:event params: { add: 'networkidle' }
pw:channel:event } +166ms
pw:channel:event {
pw:channel:event guid: 'frame@44f2c0a9f446a32cee5a435dd16eca6c',
pw:channel:event method: 'loadstate',
pw:channel:event params: { add: 'networkidle' }
pw:channel:event } +1s
there is also this body https://wiki.mozilla.org/WebDriver/RemoteProtocol but it seems to be pretty dead
what should it be on path/to/addon/directory?
const resp = await client.installTemporaryAddon("path/to/addon/directory");
should you download the extension and put it in a regular folder and write the path to it?
Bump, please add Firefox support(Java)
Hello all, team that I work in is also very interested in having Firefox extension support in Playwright. This feature would greatly enhance our testing capabilities and streamline our processes. We hope this feature gets prioritized. Thank you!
really need this guys
+1
My team and I really need this feature request. Thanks!
add please
Add it, please! It's useful
+1
Bumping this up. Please bring this much needed feature.
guys plz implement this :)
This would be great