microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
63.81k stars 3.46k forks source link

[Feature] Playwright as a Chromium extension #23514

Open ruifigueira opened 1 year ago

ruifigueira commented 1 year ago

I've been working on a PoC to compile playwright into a chromium extension. You can find my fork here: https://github.com/ruifigueira/playwright-crx.

I was able to make it work (with some limitations, of course).

Here is a small video of the recorder as a chrome devtools panel:

https://github.com/microsoft/playwright/assets/1374559/ad9ae9b7-a4f5-4abf-b04e-3356f2f6f777

The core of this integration is a ConnectionTransport implementation (see crxTransport.ts) that mostly uses chrome.debugger API.

This API is per tab (we need to provide chrome tab ID to attach it), so for now it can only handle one tab at a time.

Besides, some CDP methods are not supported under chrome.debugger, so I had to emulate them.

To build the chrome extension:

npm ci
npm run build

Then, In chrome, just add an unpacked extension pointing to packages/playwright-core/lib/webpack/crx.

image

After that, it should be available in devtools as a panel with name Playwright Recorder. Try to record and inspect some elements to ensure everything works fine.

Let me know yout thoughts!

pavelfeldman commented 1 year ago

@ruifigueira this looks very impressive! What kind of feedback are you looking for?

In terms of priorities, we like to generate code into the editor (VS Code), but given how ubiquitous Chrome DevTools are, it feels like a nice addition to the suite. So if we can figure out a good maintenance story and cover it with enough tests, we can accept the contribution!

I think the major obstacle is the collection of the polyfills (vite-plugin-node-polyfills). Your approach is great - it is minimally intrusive to Playwright code, but at the same time it is the most brittle. I wonder if there is a middle ground where we don't pollute our code with too many unnecessary abstractions, yet we can compile our code with the explicit platform externs. Think explicit platformBundle that is implemented via the node internals and mocked by the browser). It might easily get out of hand, but I would at least be interested in what it could look like.

pavelfeldman commented 1 year ago

I wonder if there is a middle ground where we don't pollute our code with too many unnecessary abstractions

Looked at our third party dependencies and this breaks fairly quickly against their extensive use of builtins. Even if we abstract our code, it'll still be a problem in thier's.

ruifigueira commented 1 year ago

@pavelfeldman thanks for the feedback.

Honestly, I think this approach for shimming / polyfilling those thirdparty dependencies is not that bad. I've been battling a little bit with vite trying to make it replace problematic code and current implementation using define is far from great, but if we can properly replace all require('./utilsBundleImpl') and a few more node-ish stuff, I would be quite happy.

Besides that, right now I'm instantiating the full playwright stuff by calling the createInProcessPlaywright but probably creating a new BrowserContext or something similar and start from there, it would be a wiser solution

pavelfeldman commented 1 year ago

I'm not too concerned about these, we can always fix it in the code we own. Unfortunately, we are using some third party node modules that will also require fs and alike without us calling any methods that require those. So while we can solve this problem for ourselves, we can't solve it for others.

I looked at the https://github.com/niksy/node-stdlib-browser#package-contents and I don't think we'd be comfortable shipping something that uses those stubs in production: often times there is no clear ownership and some modules aren't even semverd. Unfortunately, going that route would make us easily compromised.

We can probably accept patches upstream that help you get rid of defines: massage utilsBundle in a way that you can consume it (not sure why it did not work out of the box). I was hoping you could teach vite to bundle the package.json files too. Third party modules that you stub there seem to be isomorphic. So all in all, getting rid of defines sounds doable.

ruifigueira commented 1 year ago

Before addressing the isomorphic "decoupling", I refactored playwright-core a little bit:

You can check those changes in 2b3b58ab5af . I tried to be as minimalistic as possible in my changes on your code base.

With that I refactored vite on my side (0bc67c8a5815bfdac1703c78b0a4ce9aaa93a7b9):

aslushnikov commented 1 year ago

@pavelfeldman Pavel is not available right now, so I'll mark this as 1.36 so that we don't forget about it.

ruifigueira commented 1 year ago

Hi @pavelfeldman

I was on vacations, but I'm still working on this :)

For testing, the goal is to use your current page tests as much as possible. The idea is to run tests in a chrome extension worker service, and for that we send the test body to run there, similar to playwright evaluate calls to execute code on the browser.

Of course, tests that depend on functions defined outside the test will fail, which is a big limitation on this approach, but I was able to run it and more than 1k tests ran successfully.

You can check a PoC for that in 872a7556667a96afc114a4d28eee096fb79e62dc

By setting PWPAGE_IMPL to crx, it will run tests using that mechanism. I changed WorkerMain a bit so that it would serialize the test function and send it to the service worker to run there.

damartripamungkas commented 8 months ago

Saya sedang mengerjakan PoC untuk mengkompilasi penulis naskah menjadi ekstensi chromium. Anda dapat menemukan garpu saya di sini: https://github.com/ruifigueira/playwright-crx .

Saya dapat membuatnya berfungsi (tentu saja dengan beberapa keterbatasan).

Berikut adalah video kecil perekam sebagai panel chrome devtools:

chrome_pA3XQPGFEU.mp4 Inti dari integrasi ini adalah ConnectionTransportimplementasi (lihat crxTransport.ts ) yang sebagian besar menggunakan chrome.debugger API .

API ini per tab (kita perlu memberikan ID tab chrome untuk melampirkannya), jadi untuk saat ini hanya dapat menangani satu tab dalam satu waktu.

Selain itu, beberapa metode CDP tidak didukung chrome.debugger, jadi saya harus menirunya.

Untuk membuat ekstensi chrome:

npm ci
npm run build

Kemudian, di chrome, cukup tambahkan ekstensi yang belum dibongkar yang menunjuk ke packages/playwright-core/lib/webpack/crx.

gambar

Setelah itu, seharusnya tersedia di devtools sebagai panel dengan nama Playwright Recorder . Cobalah untuk mencatat dan memeriksa beberapa elemen untuk memastikan semuanya berfungsi dengan baik.

Beri tahu saya pendapat Anda!

can you help me, i dont see playwright-cfx in inspect

image

ruifigueira commented 8 months ago

I replaced the devtool panel with an action button / context menu to trigger Playwright CRX. For more details see the section Recorder in https://github.com/microsoft/playwright/pull/24020#issue-1787104044.

ruifigueira commented 2 months ago

Different approach, now compatible with Firefox too:

https://github.com/microsoft/playwright/pull/30347

ducan-ne commented 2 months ago

This is awesome, I've made something similar with pptr, but now playwright is much better than in apis. Can't wait to use it