playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] support for Chrome extension popup testing

Open aslushnikov opened this issue 3 years ago • 10 comments

(originally coming from https://github.com/microsoft/playwright/issues/5586)

Playwright can test background pages: https://playwright.dev/docs/api/class-chromiumbrowser?_highlight=extension

However, there's no support to test extension pop-ups.

aslushnikov avatar Feb 24 '21 16:02 aslushnikov

This feature is in pretty high demand here: https://github.com/puppeteer/puppeteer/issues/2486 I hope it would be implemented somewhere eventually.

maximtop avatar Mar 10 '21 21:03 maximtop

From a Chrome extension point of view, popups are fundamentally the same as other pages hosted on chrome-extension:// origins. Popups just go one step further: we would need to be able to programmatically activate the popup.

It would be amazing if this feature was implemented in a way that allowed for testing other contexts like options pages, etc.

jacksteamdev avatar Aug 11 '21 15:08 jacksteamdev

From a Chrome extension point of view, popups are fundamentally the same as other pages hosted on chrome-extension:// origins. Popups just go one step further: we would need to be able to programmatically activate the popup.

It would be amazing if this feature was implemented in a way that allowed for testing other contexts like options pages, etc.

Particularly considering manifest v3 has done away with background pages! Wtf?! The whole change is really starting to feel non-sensical at this point. Regardless it would be nice to still have a way to test moving forward.

june07 avatar Aug 23 '21 06:08 june07

Does anybody have current workarounds that will let us open the extension popup?

paambaati avatar Oct 22 '21 05:10 paambaati

Does anybody have current workarounds that will let us open the extension popup?

I didn't find any workaround to actually open the popup window. My workaround is finding the extension id and use it to open a page in tab. Code is here:

https://github.com/xcv58/Tab-Manager-v2/blob/master/packages/integration_test/util.ts#L55-L59

xcv58 avatar Oct 22 '21 17:10 xcv58

What about extension context menu items?

Is there any way to trigger these via playwright?

related:

  • https://github.com/puppeteer/puppeteer/issues/2486
  • https://developer.chrome.com/docs/extensions/mv2/messaging/
  • https://playwright.dev/python/docs/chrome-extensions

pirate avatar Dec 21 '21 22:12 pirate

@pirate It's not the same, but you might try using the undocumented Event#dispatch method to simulate events.

image

jacksteamdev avatar Dec 22 '21 14:12 jacksteamdev

Another workaround, dispatching the chrome.action.onClicked event from the extension background service worker:

const test = base.extend<{}, WorkerContextFixture>({
    // ... 

    extension: async ({ context }, use) => {
        // modify this if you're still using background pages
        const extWorker = context.serviceWorkers()[0];

        use({
            activateActiveTab: async () =>
                await extWorker.evaluate(() => {
                    // @ts-ignore
                    chrome.tabs.query({ active: true }, (tabs) => {
                        // @ts-ignore
                        chrome.action.onClicked.dispatch(tabs[0]);
                    });
                }),
        });
    },
});

phgn0 avatar Jun 08 '22 07:06 phgn0

After the popup is displayed using a browser action, is there any way to obtain the popup page in Playwright? browser_context.pages returns a list of pages but it does not include the extension popup.

ducalpha avatar Jul 01 '22 18:07 ducalpha

Please, for the love of Bob...make it so Playwright can interact with extension popup elements.

SudoPumpkin avatar Sep 10 '22 01:09 SudoPumpkin

+1 on this as I believe this issue is blocking the popup displayed by chrome.identity.getAuthToken({interactive: true}, (token, grantedscopes_ => { .... } ) which means no testing anything behind authentication in my Chrome extension.

mattemoore avatar Sep 27 '22 23:09 mattemoore

any updates on this issue?

BoMarley avatar Oct 12 '22 08:10 BoMarley

I'm curious what the scope of this feature is. Depending on the extension an amount of popup behavior can be tested with the await page.goto(`chrome-extension://${extensionId}/popup.html`); solution from https://playwright.dev/docs/chrome-extensions. But is the goal of this feature to be able to trigger the extension popup normally like a user would so you can test the extension within the context of a specific tab/website? Because that would be great.

As I understand it currently there is no way to test behavior of an extension that requires a website to be open while the popup is open.

fedorareis avatar Nov 03 '22 02:11 fedorareis

@fedorareis I believe the point is to be able to write tests that confirm a user flow involving an extension popup works end to end. E.g.

  1. Open extension tab
  2. Click on a button that opens extension popup
  3. Click some buttons and type some text in the popup
  4. Close popup and confirm the changes in popup triggered expected changes in main page

For clarity my case is a little different...i would like to test the following flow end to end:

  1. Open extension tab
  2. Click a button that calls chrome.identity.getAuthToken({interactive: true})
  3. Internal chrome popup window opens, user select account to log into Chrome extension backend with, click accept button on oauth authorization screen
  4. Popup window closes, user returns to chrome extension main page, assert user is logged in and UX reacts accordingly

Hopefully this helps clarify.

mattemoore avatar Nov 03 '22 17:11 mattemoore

This is fully supported now with the https://playwright.dev/docs/chrome-extensions !

aslushnikov avatar Feb 09 '23 19:02 aslushnikov

That's amazing progress, thanks @aslushnikov!

On a read-through of those docs, I don't see anything about extension context menu or menubar icon testing. How can we use this new functionality to test browser extension context menus as described here: https://github.com/microsoft/playwright/issues/5593#issuecomment-999146185

pirate avatar Feb 10 '23 01:02 pirate

If am getting this right, the support was for the headless mode, not for the extension popup testing. I don't think this [Feature] should be considered closed. Thoughts?

Ameerplus avatar Feb 10 '23 10:02 Ameerplus

@aslushnikov can our tests now interact with the chrome.identity.launchWebAuthFlow() authentication window? https://developer.chrome.com/docs/extensions/reference/identity/#type-WebAuthFlowDetails

https://www.google.com/url?sa=i&url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F56360810%2Flogin-page-opened-with-identity-launchwebauthflow-doesnt-show-accounts-i-logged&psig=AOvVaw2yyoeXsZPUKW3uJwJjbCi8&ust=1676123954678000&source=images&cd=vfe&ved=0CBAQjRxqFwoTCPiXmLmOi_0CFQAAAAAdAAAAABAE

mattemoore avatar Feb 10 '23 13:02 mattemoore

Hey folks! This issue's scope was popup testing, which is supported. (see https://playwright.dev/docs/chrome-extensions) Answering the follow-up questsions:

On a read-through of those docs, I don't see anything about extension context menu or menubar icon testing. How can we use this new functionality to test browser extension context menus as described here

@pirate context menu testing is not possible as of today. Please file a separate feature request!

If am getting this right, the support was for the headless mode, not for the extension popup testing. I don't think this [Feature] should be considered closed. Thoughts?

@Ameerplus this would be an issue request to Chromium. There's some new headless mode that might be helpful, please see the discussion here: https://bugs.chromium.org/p/chromium/issues/detail?id=706008

can our tests now interact with the chrome.identity.launchWebAuthFlow() authentication window?

@mattemoore if they can't, then please file a separate issue! Narrow-scope issues are way easier to manage & gauge interest.

aslushnikov avatar Feb 13 '23 18:02 aslushnikov

I wanted to trigger the extension popup using a button click on my main page and do something on the extension within the context of tab/website. After performing some actions on the extension popup, I need to verify that the changes on the main page is caused by the extension.

For example, I am testing a wordpress site and I wanted to click on a button which would trigger the metamask extension. Once the metamask extension is loaded, I need to login to metamask wallet from the popup after which I can continue testing my wordpress site.

Is this possible in the current implementation in Playwright?

I read https://playwright.dev/docs/chrome-extensions doc and I couldn't find a workaround for my usecase. Please help me confirm whether this is possible or not in playwright.

wasimwazi avatar Feb 26 '23 06:02 wasimwazi

I wanted to trigger the extension popup using a button click on my main page and do something on the extension within the context of tab/website. After performing some actions on the extension popup, I need to verify that the changes on the main page is caused by the extension.

For example, I am testing a wordpress site and I wanted to click on a button which would trigger the metamask extension. Once the metamask extension is loaded, I need to login to metamask wallet from the popup after which I can continue testing my wordpress site.

Is this possible in the current implementation in Playwright?

I read https://playwright.dev/docs/chrome-extensions doc and I couldn't find a workaround for my usecase. Please help me confirm whether this is possible or not in playwright.

Did you ever get this to work? I am in the same situation.

antidoteadmin avatar Sep 25 '23 19:09 antidoteadmin

I wasn't able to interact with the pop up page of our chrome extension until I did the following using playwright-pytest with python 3.10:

  1. set up my conftest.py as suggested here
  2. navigate to my pop up page like: page_one = context.new_page() page_one.goto(f"chrome-extension://{EXTENSION_ID}/popup/popup.html")
  3. use time.sleep(3) before interacting with any element on the pop up page.

Without the time.sleep of 3 (YMMV) seconds I'm not able to interact with anything on the pop up page. I know it's an anti-pattern but nothing else worked. I tried page.wait_for_load_state(), page.wait_for_selector(), page.wait_for_url(), and element.wait_for(). Nothing worked except the static wait. Hope this helps someone. From what @aslushnikov said above, it seems like a chromium issue is causing this so who knows when/if it will be fixed but it sure would be nice to interact with that dang extension pop up.

Can anyone tell me why the time.sleep is the only thing that works here and none of the built in waiting features in playwright?

authauthentic8 avatar Sep 26 '23 01:09 authauthentic8

This is fully supported now with the https://playwright.dev/docs/chrome-extensions !

@aslushnikov the amount of functionality that can be tested by navigating to chrome-extensions://<ext-id>/popup.html is miniscule. Anything that needs to interact with the current tab won't work.

Please reopen this issue.

itsfarseen avatar Oct 16 '23 06:10 itsfarseen

Please re-open this issue as this is not implemented.

I have a chrome extension where we expect the user to open the popup on a particular page and then inject a script on that page. Just opening chrome-extensions://<ext-id>/popup.html is not sufficient to test this functionality because that page cannot use the tabs API.

Please implement a way to open the extension popup in a way that a user would interact with the extension before calling this fully supported

jermowery avatar Nov 28 '23 06:11 jermowery

Please re-open this issue as this is not implemented. I am in the same situation.

pinghe avatar Dec 03 '23 14:12 pinghe

@aslushnikov Can this please be re-opened? This is still an issue for me as well. The hack-y solution I listed above (using time.sleep(3) before trying to click on a button in the extension popup https://github.com/microsoft/playwright/issues/5593#issuecomment-1734678075) isn't preferable as it slows down testing and it doesn't allow me to fully interact with the extension popup.

authauthentic8 avatar Dec 04 '23 14:12 authauthentic8

Is there any new progress on this issue? I need to interact with the popup extension page directly instead of using chrome-extensions:///popup.html. Because not all extensions support this method.

gaohongxiang avatar Jan 28 '24 15:01 gaohongxiang

For anyone testing Chrome extensions where yout auth has to go through chrome.identity.launchWebAuthFlow API, then your page has to wait for the page event instead of the popup event.

test('can login', async ({ page, extensionId }) => {
    await page.goto(`chrome-extension://${extensionId}/newtab.html`);

    const signInButton = page.getByRole('button', { name: 'Sign in' });
    await expect(signInButton).toBeVisible();

    await signInButton.click();

    const browserContext = page.context();

    // Salesforce Login popup
    const popupPage = await browserContext.waitForEvent('page');

    await popupPage.waitForLoadState('domcontentloaded');

    await expect(popupPage).toHaveURL(/login\.salesforce\.com/);

    await popupPage.getByLabel('Username').fill(<username>);
    await popupPage.getByLabel('Password').fill(<password>);
    await popupPage.getByRole('button', { name: 'Log In' }).click();

    await popupPage.close();
});

pavitra-infocusp avatar Mar 06 '24 13:03 pavitra-infocusp

I managed to open the popup from playwright (properly, as if the user clicked on the button, not in a new tab as the doc suggests) Based on this thread: https://github.com/puppeteer/puppeteer/issues/2486

# context fixture is defined here https://playwright.dev/python/docs/chrome-extensions#testing

@pytest.fixture()
def extension(context):
    context.wait_for_event('serviceworker')
    background = context.service_workers[0]
    yield background

def test_popup_page(page: Page, extension: Extension) -> None:
    page.goto('https://example.com')
    # open popup via chrome apis directly
    extension.background.evaluate('''() => { chrome.action.openPopup(); }''')

However, I can't find a way to actually interact with popup HTML elements :(

karlicoss avatar Apr 18 '24 23:04 karlicoss

The chrome.action.openPopup(); method is deprecated, so it won't work. I tried setting a shortcut to activate the extension and simulating the shortcut via Playwright, but that also didn't work. I think Chrome doesn't allow programmatically opening the extension popup.

GorvGoyl avatar Jul 12 '24 16:07 GorvGoyl