-
Notifications
You must be signed in to change notification settings - Fork 43
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
Adding support for Android devices #79
base: master
Are you sure you want to change the base?
Conversation
Awesome! Thanks for working on this.
Android devices are already supported ;) Android devices with chrome (which is default since 4.4) don't need any further changes in wdio-screenshot. That's why we need to make sure that this PR doesn't break them.
The blank or very yellow screenshots are just some simple screenshots to test the cropping. I used just a single background color to avoid any cropping mistakes due to antialiasing or other possible error sources. I'm not even sure if this could happen and just wanted to eliminate this kind of error... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this and the tests! I reviewed your changes and added some notes.
const { isIOS } = browser; | ||
if (isIOS) { | ||
const { isMobile } = browser; | ||
if (isMobile) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really necessary for android simulators or in other words, is merging enough? iOS uses this to remove the grey line between the stiched screenshots.
For real android devices with chrome this shouldn't be executed, merging ist enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, let me check just using the merge strategy on Android.
@@ -0,0 +1,10 @@ | |||
export default { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete this file. Have a look at my other comment for the reason.
async function normalizeIOSScreenshot(browser, screenDimensions, base64Screenshot) { | ||
const toolbarHeight = 44; // bottom toolbar has always a fixed height of 44px | ||
const addressbarHeight = 44; // bottom toolbar has always a fixed height of 44px | ||
async function normalizeMobileScreenshot(browser, screenDimensions, base64Screenshot) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please create a seperate normalize function for Android. Using a normalizer that does iOS and android at the same time is just complicated and uncecessary.
I made this mistake around two years ago within an unpublished webdrivercss fork with support for iOS and Android. In the beginning it looks like a good idea but it becomes unmaintainable very quickly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
const addressbarHeight = 44; // bottom toolbar has always a fixed height of 44px | ||
async function normalizeMobileScreenshot(browser, screenDimensions, base64Screenshot) { | ||
const mobileFixedHeights = (browser.isAndroid) ? fixedHeights.android : fixedHeights.iOS; | ||
const toolbarHeight = mobileFixedHeights.toolbarHeight; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Android really have a toolbar at the bottom? I can't see any at your screenshots.
When not please remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uiii, this doesn't look like a case that is fixable. Especially with the offsets around the device screenshot and the android controls on the right side 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is a screenshot from the saucelabs video 😅
The device screenshot is just the header, page, and footer. But that will need cropping
async function normalizeMobileScreenshot(browser, screenDimensions, base64Screenshot) { | ||
const mobileFixedHeights = (browser.isAndroid) ? fixedHeights.android : fixedHeights.iOS; | ||
const toolbarHeight = mobileFixedHeights.toolbarHeight; | ||
const addressbarHeight = mobileFixedHeights.addressbarHeight; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the height of the adressbar is something that we can calculate with screenHeight - innerHeight = 77
.
In my opinion this makes all static height values unnecessary, am I wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that toolbar appears only in some cases. Is there a way to get the y offset of the viewport from the top of the screen? If so then I can calculate whether the footer appears. I think if I use screenHeight - innerHeight
and the footer is there, it will be the height of the address bar + the toolbar.
if (browser.isMobile && browser.isIOS) { | ||
normalizedScreenshot = await normalizeIOSScreenshot(browser, screenDimensions, normalizedScreenshot); | ||
// check if we have to crop navigation- & toolbar for iOS or Android | ||
if (browser.isMobile) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As already said, please separate iOS from android here for maintenance reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
if (browser.isMobile && browser.isIOS) { | ||
normalizedScreenshot = await normalizeIOSScreenshot(browser, screenDimensions, normalizedScreenshot); | ||
// check if we have to crop navigation- & toolbar for iOS or Android | ||
if (browser.isMobile) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to make sure that you doesn't break real android devices with chrome here. They don't need additional cropping as the screenshots are the same like the desktop chrome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, does the viewportHeight
and screenHeight
return different values for real device chrome? If not then it should just pass through without cropping. If so then maybe there is a way to check for emulators.
@@ -9,3 +9,6 @@ yarn.lock | |||
# project | |||
.tmp | |||
lib | |||
|
|||
# Mac OSX | |||
.DS_Store |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OS dependent stuff should be ignored in a global .gitignore file, but I'm fine with merging this in to avoid this in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean by a global .gitignore
, I presumed that was this.
@@ -83,7 +83,7 @@ export default class ScreenDimensions { | |||
} | |||
|
|||
getScale() { | |||
if (this.isIOS) { | |||
if (this.isIOS || this.isAndroid) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a test case for this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me see if I can add some off of the existing ones
Thanks for following up! Wasn't sure if I would get a response 😄
Hmm, what kind of android support exists already? I do testing through Saucelabs Simulator/Emulator, and this didn't work out of the box. The header on android gets stitched onto each screenshot and looks quite a mess. Perhaps this isn't an issue for real devices? But happens on emulator and it's unusable. |
Every android with chrome should work in theory. We tried some Nexus & Samsung devices. But I think that simulators never have chrome, just the old android browser. Give the real devices from saucelabs a try ;) |
Background
wdio-screenshot currently supports iOS devices but it doesn't seem like a big jump to also start supporting Android as well. This adds image normalizing support for android devices as well.
Note: I was only able to test this on Android Simulator for 4.4 and 5.1 through SauceLabs and it was working fine for me. It's possible that other versions may not be supported, but limited is better than nothing 🤷♂️
Changes
ScreenDimension#getScale
to check for Android as well.ScreenshotStrategyManager
to checkisMobile
instead ofisIOS
fixedHeights.js
file to keep track of mobile devices' known fixed heights. If different versions of Android/iOS have different heights, this can be further granulated.normalizeScreenshot
to check for mobile and take into account the type of device you are using..gitignore
to ignore mac.DS_Store
files