Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] support for Chrome extension popup testing #5593

Closed
aslushnikov opened this issue Feb 24, 2021 · 30 comments
Closed

[Feature] support for Chrome extension popup testing #5593

aslushnikov opened this issue Feb 24, 2021 · 30 comments
Labels
browser-chromium P3-collecting-feedback upstream This is a bug in something playwright depends on, like a browser.

Comments

@aslushnikov
Copy link
Collaborator

(originally coming from #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.

@maximtop
Copy link

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

@jacksteamdev
Copy link

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.

@june07
Copy link

june07 commented Aug 23, 2021

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.

@paambaati
Copy link

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

@xcv58
Copy link

xcv58 commented Oct 22, 2021

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

@pirate
Copy link

pirate commented Dec 21, 2021

What about extension context menu items?

Is there any way to trigger these via playwright?

related:

@jacksteamdev
Copy link

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

image

@phgn0
Copy link

phgn0 commented Jun 8, 2022

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]);
                    });
                }),
        });
    },
});

@ducalpha
Copy link

ducalpha commented Jul 1, 2022

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.

@SudoPumpkin
Copy link

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

@mattemoore
Copy link

mattemoore commented Sep 27, 2022

+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.

@BoMarley
Copy link

any updates on this issue?

@fedorareis
Copy link

fedorareis commented Nov 3, 2022

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.

@mattemoore
Copy link

mattemoore commented Nov 3, 2022

@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.

@aslushnikov
Copy link
Collaborator Author

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

@pirate
Copy link

pirate commented Feb 10, 2023

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: #5593 (comment)

@Ameerplus
Copy link

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?

@aslushnikov
Copy link
Collaborator Author

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.

@wasimwazi
Copy link

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.

@antidoteadmin
Copy link

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.

@authauthentic8
Copy link

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?

@itsfarseen
Copy link

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.

@jermowery
Copy link

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

@pinghe
Copy link

pinghe commented Dec 3, 2023

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

@authauthentic8
Copy link

@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 #5593 (comment)) isn't preferable as it slows down testing and it doesn't allow me to fully interact with the extension popup.

@gaohongxiang
Copy link

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.

@pavitra-infocusp
Copy link

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();
});

@karlicoss
Copy link

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: puppeteer/puppeteer#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 :(

@GorvGoyl
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
browser-chromium P3-collecting-feedback upstream This is a bug in something playwright depends on, like a browser.
Projects
None yet
Development

No branches or pull requests