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 browser zoom #2497

Open
arjunattam opened this issue Jun 8, 2020 · 18 comments
Open

[Feature] Support browser zoom #2497

arjunattam opened this issue Jun 8, 2020 · 18 comments

Comments

@arjunattam
Copy link
Contributor

(Logging a feature request – please vote if your scenario needs it and help us prioritize!)

To support accessibility requirements, web developers often need to test their application on higher zoom levels like 200%. Relevant WCAG doc: "Ensuring that there is no loss of content or functionality when the text resizes and text containers do not change their width".

To support this, the Playwright API needs to be able to emulate a higher zoom level, preferably at the browser context level.

@JoelEinbinder
Copy link
Contributor

I think this is doable today with setting the device pixel ratio. But its not a great api. We should match the buttons you get in a browser. I think something like await page.zoom(1.5) to zoom to 150% would be nice.

Chromium will remember the zoom for an origin. Is this important behavior? If so, we'd need to tap into the real browser zoom instead of just device pixel ratio.

@maustin
Copy link

maustin commented Jan 5, 2021

(This comment is related to the bug originally reported here: #2768)

I've been doing some digging into the issue of Playwright clicks not happening correctly when page zoom is not 100%.
It actually looks like Playwright is doing everything correctly on its side. Calling elementHandle.boundingBox() returns a rect with the expected values. But calling elementHandle.click(), while it does pass actionability checks, fails to click on the element. The reason I think is with Chromium's mouseEvent handler. It appears Chromium is expecting non-scaled x and y values.

Indeed, if I patch Playwright's server/input.ts Mouse.move() method, these lines:

this._x = x;
this._y = y;

become:

this._x = x * devicePixelRatio;
this._y = y * devicePixelRatio;

The click action then works as expected.

(My full patch adds a scale property to elementHandle.click(options) so the device pixel ratio can be passed down to the call. The above code is just for demonstration.)

EDIT: devicePixelRatio is an unreliable value for zoom. I've switched to getting zoom factor via extension call chrome.tabs.getZoom()

@ronvoluted
Copy link

Very desirable. Adding to research, this attempt isn't able to emulate zoom either:

  await page.keyboard.down('Control');
  
  for (let i = 0; i < 7; i++) {
    await page.keyboard.press('+');
  }
  
  await page.keyboard.up('Control');

@Theorian
Copy link

Theorian commented Apr 5, 2021

Would love this feature as I am sometimes on a monitor with a low resolution

@janjdk
Copy link

janjdk commented Sep 1, 2021

I am waiting for this to work. Any news on when zoom will be handled correct by click and other operations?

@lakshmanp21

This comment has been minimized.

1 similar comment
@tl3821

This comment has been minimized.

@sureshahead

This comment has been minimized.

@Theorian

This comment has been minimized.

@johsin18
Copy link

johsin18 commented Feb 7, 2022

This would also enable testing of high resolution displays, as the browser zoom is equivalent to display scaling. So this would be very much appreciated.

@vlaraort
Copy link

vlaraort commented May 2, 2022

As a point, the accessibility requirement is to zoom TEXT to 200%, not the full layout, which would be equivalent to resize the width to 50%

Currently chrome doesn't support text scaling, but firefox and safari does, so probably would be nice if emulateMedia would support this in those browsers

Also, this text scaling can be configured in OS level, like "prefers-reduced-motion" or light/dark themes, which can be emulated with playwright, so maybe there is a way there

@BilalMohammad5
Copy link

any info on how to perform chromezoomusinf playwright ?

@ChrisMaze
Copy link

Any updates?

@tbrains
Copy link

tbrains commented May 29, 2023

+1

@jpjagt
Copy link

jpjagt commented Jan 10, 2024

I found a workaround to achieve setting native zoom level in Chromium (and not through the CSS zoom attribute, which can mess up some layouts), inspired by a similar SO question for Selenium.

You can achieve it by browsing to chrome://settings and actually setting the zoom level there through JS. Example for Python:

zoom_level = "1.25"
driver.goto("chrome://settings")
driver.evaluate(f"chrome.settingsPrivate.setDefaultZoom({zoom_level});")

Hope this helps (:

@rob-smallshire
Copy link

@jpjagt Sadly, using Playwright, page.goto("chrome://settings") causes Chrome to open a new window, invalidating the page object.

@michaelact
Copy link

I experienced the same issue and asked ChatGPT for advice. They recommended the following solution:

from playwright.sync_api import sync_playwright

def setup_edge_browser(zoom_level: float):
    # Start Playwright and launch Microsoft Edge browser in headless mode
    with sync_playwright() as p:
        browser = p.chromium.launch(channel="msedge", headless=True)
        context = browser.new_context()
        
        # Setting the viewport to simulate zoom by scaling the dimensions
        viewport_width = context.viewport['width']
        viewport_height = context.viewport['height']
        context.set_viewport_size(width=int(viewport_width / zoom_level), height=int(viewport_height / zoom_level))
        
        # Now you can use context.new_page() to open new pages with the updated viewport, simulating the zoom effect
        # ...

        # Don't forget to close the browser
        browser.close()

# Example usage: set up Edge with a zoom level of 90%
setup_edge_browser(zoom_level=0.9)

It resolved my issue, and I hope it can help you as well.

@ConcernedHobbit
Copy link

Would love to be able to do this, combined with jest-image-snapshot it would be easier to snap crisp snapshots of very detailed components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests