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

Any way to force CSS media queries to detect mobile #970

Open
windycom opened this issue Nov 28, 2017 · 24 comments
Open

Any way to force CSS media queries to detect mobile #970

windycom opened this issue Nov 28, 2017 · 24 comments
Labels
prevent-stale mark an issue so it is ignored by stale[bot] topic: mobile testing topic: native events type: unexpected behavior User expected result, but got another

Comments

@windycom
Copy link

First of all THANK YOU for excellent tool. We (front end developers) have been waiting years for this tool.

There is just one small issue. Using cy.viewport('type-of-mobile-phone') makes testing iframe smaller, but CSS media queries and window.screen.width, height remains the same (since it resolves actual size of screen.

Is there any possible way how to fix this? I was doing some research, and only idea I have is to implement somehow Google Dev Tools protocol, that is able to force Chrome to fake anything.

https://chromedevtools.github.io/devtools-protocol/

@jennifer-shehane jennifer-shehane added the type: unexpected behavior User expected result, but got another label Nov 28, 2017
@jennifer-shehane
Copy link
Member

Related comment on devtools protocol: #311 (comment)

@brian-mann
Copy link
Member

That part of the debugger protocol would only work for Chrome and is not cross browser compatible. If we exposed that, it would either have to be restricted to Chrome only.

Can you provide me an example of CSS media queries not working? Those should be bound to the window, not the screen.

I understand that the screen API's don't account for the iframe - but to work around this is fairly trivial, you create wrapper functions around those values and use cy.stub to force them to return what it is you want returned. Then your application reacts as if the screen had those dimensions.

Having some code in regards to what you're doing with screen would also be helpful.

@jennifer-shehane jennifer-shehane added the stage: needs information Not enough info to reproduce the issue label Nov 28, 2017
@windycom
Copy link
Author

Media query is

@media only screen and ( max-device-width: 736px ) {
...
}

and it is recommended detection of mobile phone. I think cypress works as expected, since media queries are bound to device, not screen.

@brian-mann
Copy link
Member

Yeah I can't think of a way around this other than to hide the Cypress UI and then change the width and height of the actual browser window. It's actually possible to do - those API's are exposed to us - but probably not worth the effort.

@windycom
Copy link
Author

No problem will find a way

@windycom
Copy link
Author

Just now I have tested Facebook, Gmail and Twitter and all of them use media queries based on device-width not a browser window, and by this they decide if they will use mobile or desktop layout. Therefore I think, that forcing cy.viewport to fake device width would be nice addition. I know that this task is very, very, very complicated but trust me, that can be useful as hell. Even when limited to Chrome.

@windycom windycom reopened this Nov 29, 2017
@brian-mann
Copy link
Member

Agreed. This is possible to do and we will do this - even if its just for Chrome.

This belongs in the same category as "native events", which is something we can implement. @chrisbreiding is scheduled to start working on cross browser support in December and that's when we'll switch everything over.

We can do this by using the underlying debugger protocol as opposed to the extensions which is how we currently automate chrome. Once we do that, we'll be able to fire any kind of native event, but also expose and even lower level API that would enable you to take advantage of anything that the debugger protocol offers.

If you're curious these other issues talk more detail about the switchover:

@ilblog
Copy link

ilblog commented Nov 29, 2017

Thanx a lot

@thebluick
Copy link

thebluick commented Jul 17, 2018

Any updates on this? I'm currently running into issues trying to properly spoof mobile devices and its breaking my tests.

@jennifer-shehane jennifer-shehane removed the stage: needs information Not enough info to reproduce the issue label Jul 17, 2018
@jennifer-shehane
Copy link
Member

Hi @thebluick, we still have this on our roadmap, but no defined deadline or work done for this issue at the moment.

@wachunga
Copy link

wachunga commented Jul 8, 2019

With the default 1000px viewport, window.matchMedia('(max-width: 511px)') returns matches: true, which is clearly wrong. (You can put any width there - it will always match.) In the console after the tests run, it works as expected.

max-device-width also doesn't seem to relate to the viewport setting and is also deprecated
https://developer.mozilla.org/en-US/docs/Web/CSS/@media/device-width

@DevScissors
Copy link

The larger issue I am having dealing with this is getting some sort of weird hybrid where the window size is 1280x720 but the rendering is showing the mobile/responsive view. This is breaking tests since we have a different layout in mobile. Is there no way to preserve viewport size and/or reset it manually?

@jennifer-shehane jennifer-shehane changed the title Any way ho to force CSS media queries to detect mobile Any way to force CSS media queries to detect mobile Jan 28, 2020
tdf-gerrit pushed a commit to LibreOffice/online that referenced this issue Mar 20, 2020
Broken since: b62dcc0

The issue here cypress sets the window size and not the device size
when tries to emulate mobile view.
cypress-io/cypress#970

For now, let's keep window size media rules too.

[tml: Window size changes depending on orientation. Device size does
not. We need to change each rule that used only max-device-width into
one using two subrules using max-width combined with comma (i.e. the
OR operator), one for portrait using 767px as the limit, one for
landscape using 1023px as the limit.]

We do this in other places of the css code anyway. In a long term, it
would be good to find a better way to emulate mobile view by cypress
or to detect mobile from JS code, so we can enable mobile mode easily
for cypress tests.

Change-Id: Ic7974f44fcbf6ed2883e93acd28153709514c216
tdf-gerrit pushed a commit to LibreOffice/online that referenced this issue Mar 20, 2020
Broken since: b62dcc0

The issue here cypress sets the window size and not the device size
when tries to emulate mobile view.
cypress-io/cypress#970

For now, let's keep window size media rules too.

[tml: Window size changes depending on orientation. Device size does
not. We need to change each rule that used only max-device-width into
one using two subrules using max-width combined with comma (i.e. the
OR operator), one for portrait using 767px as the limit, one for
landscape using 1023px as the limit.]

We do this in other places of the css code anyway. In a long term, it
would be good to find a better way to emulate mobile view by cypress
or to detect mobile from JS code, so we can enable mobile mode easily
for cypress tests.

Change-Id: Ic7974f44fcbf6ed2883e93acd28153709514c216
@Sjeiti
Copy link

Sjeiti commented Jan 26, 2021

A bit of a crude solution that worked for me was swapping min-device-width for min-width at runtime during the test. It's a bit of a hack and not for all use-cases, but it works.

Cypress.Commands.add('swapDeviceWidth', () => {  
  cy.document().then(doc=>{  
    let replaced = 0  
    Array.from(doc.styleSheets).forEach(sheet => {  
      try {  
        Array.from(sheet.cssRules).forEach((rule, index) => {  
          const {cssText} = rule  
          const regexQuery = /(\(\s*)(min|max)-device-(width|height)(\s*:)/  
          const hasDeviceWidth = cssText.match(regexQuery)  
          if (hasDeviceWidth) {  
            const newRule = cssText.replace(regexQuery, '$1$2-$3$4')  
            sheet.removeRule(index)  
            sheet.insertRule(newRule, index)  
            replaced++  
          }  
        })  
      }catch(err){/* prevent InvalidAccessError on external sources*/}  
    })  
    cy.log(`Replaced ${replaced} -device- rules`)  
  })  
})

@waterplea
Copy link

This is not just about resolution, there's also these things to detect touch devices:
@media only screen and (hover: none) and (pointer: coarse)

@pganster
Copy link

pganster commented Nov 16, 2021

In this issue on the Material-UI library and this Stackoverflow question it is discovered that Cypress tests on headless chrome with Material UI's DatePicker component fail, if they use type() and clear() on the DatePicker.

The reason behind this is that Material UI renders the MobileDatePicker component, since the query @media (pointer: fine) doesn't match (similar to the query of @waterplea). The mobile component only has readonly inputs, therefore it can't be cleared or typed into with .type() and .clear() (as opposed to the DesktopDatePicker component, which has typable and clearable inputs).

As far as I know, there is no way for Cypress to force such a media query to match, so this is a feature that would be nice.

@dsheng123
Copy link

Any updates on this? Would love to be able to set pointer media query in addition to viewport size in the cypress config.

Issue is also the Material Date picker as mentioned by @pganster

@sruthiantony-hub
Copy link

+1 having the ability to set pointer/ other MediaQuery params is much needed to automate mobile use cases. Please share if there are any workarounds. Thanks!

@archfz
Copy link

archfz commented Mar 27, 2023

MUI X pickers detects mobile based on touch, and the lack of feature for this prevents us from visual testing these components.

@kaceycleveland
Copy link

Running into the same with the latest MUI X pickers too. If I find a solution will update here accordingly.

@kaceycleveland
Copy link

For those running into this issue, I found a "fix"/work-around. MUI X date pickers have a prop desktopModeMediaQuery as detailed here:
https://mui.com/x/api/date-pickers/date-picker/

It has a default value of '@media (pointer: fine)' which results in the issue pertaining to this thread. My fix is to make this dependent on screen size rather then pointer: fine so cypress viewport changes can effectively render the two different versions accurately. Really I think the fix should be a way to mock pointer: file on Cypress but I had no luck in doing that in a clean way.

My specific solution was to provide a default prop to my MUI theme with the given media query:

    MuiDatePicker: {
      defaultProps: {
        desktopModeMediaQuery: `(min-width: ${breakpoints.md}px)`,
      },
    },
    ```

@cypress-app-bot
Copy link
Collaborator

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

@cypress-app-bot cypress-app-bot added the stale no activity on this issue for a long period label Sep 27, 2023
@cypress-app-bot
Copy link
Collaborator

This issue has been closed due to inactivity.

@cypress-app-bot cypress-app-bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 11, 2023
@gyurielf
Copy link

This issue shouldn't be closed, because it's still actual.

@cypress-app-bot cypress-app-bot removed the stale no activity on this issue for a long period label Oct 21, 2023
@cypress-app-bot
Copy link
Collaborator

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

@cypress-app-bot cypress-app-bot added the stale no activity on this issue for a long period label Apr 18, 2024
@jennifer-shehane jennifer-shehane added prevent-stale mark an issue so it is ignored by stale[bot] and removed stale no activity on this issue for a long period labels Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
prevent-stale mark an issue so it is ignored by stale[bot] topic: mobile testing topic: native events type: unexpected behavior User expected result, but got another
Projects
None yet
Development

No branches or pull requests