Using detox to look at UI in different orientations (Android) - android

So I am using detox to take screenshots of my app. I'm using a connected Android device. The device.takeScreenshot function works. Now what is the best way to see what my app looks like on different orientations? Is the only way to just change the tablet orientation and run the test again? Or is there a smarter way to do it?

I'm not entirely sure what you're asking here, but in order to change orientation you can use device.setOrientation().
Is the only way to just change the tablet orientation and run the test again?
To me, this sounds like two separate use cases (portrait vs. vertical). Would be easier to maintain.
Lastly, as far as screenshot testing is concerned, you might find the practices described in Detox's screenshots guide useful:
...
the concept is mainly useful for verifying the proper visual structure and layout of elements appearing on the device's screen, in the form of a snapshot-test. Namely, by following these conceptual steps:
Taking a screenshot, once, and manually verifying it, visually.
Storing it as an e2e-test asset (i.e. the snapshot).
Using it as the point-of-reference for comparison against screenshots taken in consequent tests, from that point on.
const fs = require('fs');
describe('Members area', () => {
const snapshottedImagePath = './e2e/assets/snapshotted-image.png';
it('should greet the member with an announcement', async () => {
const imagePath = (take screenshot from the device); // Discussed >below
expectBitmapsToBeEqual(imagePath, snapshottedImagePath);
});
});
function expectBitmapsToBeEqual(imagePath, expectedImagePath) {
const bitmapBuffer = fs.readFileSync(imagePath);
const expectedBitmapBuffer = fs.readFileSync(expectedImagePath);
if (!bitmapBuffer.equals(expectedBitmapBuffer)) {
throw new Error(`Expected image at ${imagePath} to be equal to image >at ${expectedImagePath}, but it was different!`);
}
}
Important: The recommended, more practical way of doing this, is by utilizing more advanced 3rd-party image snapshotting & comparison tools such as applitools.

Related

R shiny mobile app: prevent PullToRefresh

Context: I am developing a mobile Shiny app using the shinyMobile package, which is a wrapper for the famous framework7 HTML template.
In my app, the user has to make a selection of attributes on a first tab using multiple dropdown lists, and then, on the other tabs, some output is produced. Each tab requires the user to scroll up and down to access all the content and in this process, very often the 'pull to refresh' feature is triggered.
This is really annoying, because the entire attribute selection and output are lost, and the user has to start over from scratch.
What I tried: based on this SO thread which pointed me to this Google developer page, I tried setting the CSS overscroll-behavior property to contain with: body {overscroll-behavior-y: contain;}. PROBLEM: It does not work for me! (tested on Chrome Android)
Minimal reproducible example:
default app, deployed here
library(shiny);library(shinyMobile)
shiny::shinyApp(
ui = f7Page(
f7Card(
h5('try to pull to refresh. normally it should work.')
)
),
server = function(input, output) {}
)
Supposedly fixed app, deployed here
library(shiny);library(shinyMobile)
shiny::shinyApp(
ui = f7Page(
tags$style(type='text/css', '.body{overscroll-behavior-y: contain;}'),
f7Card(
h5('try to pull to refresh. Normally it should not work.')
)
),
server = function(input, output) {}
)
Hope you guys can reproduce my issue and identify what is amiss!!!
You might want to change your css part to: html,body{overscroll-behavior-y: contain;}, see https://stackoverflow.com/a/42509310/3502164.
Then it works for me on my mobile (android chrome).
Reproducible example:
library(shiny)
library(shinyMobile)
app <- shiny::shinyApp(
ui = f7Page(
tags$style(type='text/css', 'html,body{overscroll-behavior-y: contain;}'),
f7Card(
h5('try to pull to refresh. Normally it should not work.')
)
),
server = function(input, output) {}
)
# use host config to access app from mobiles in the same network
shiny::runApp(appDir = app, host = '0.0.0.0')

Taking Screenshots Using Qt C++ on Android

thanks for checking my question out!
I'm currently working on a project using Qt C++, which is designed to be multi-platform. I'm a bit of a newcoming to it, so I've been asked to set up the ability to take screenshots from within the menu structure, and I'm having issues with the Android version of the companion app.
As a quick overview, it's a bit of software that send the content of a host PC's screen to our app, and I've been able to take screenshots on the Windows version just fine, using QScreen and QPixmap, like so:
overlaywindow.cpp
{
QPixmap screenSnapData = screenGrab->currentBackground();
}
screenGrabber.cpp
{
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
}
Unfortunately, Android seems to reject QScreen, and with most suggestions from past Google searches suggesting the now-deprecated QPixmap::grab(), I've gotten a little stuck.
What luck I have had is within the code for the menu itself, and QWidget, but that isn't without issue, of course!
QFile doubleCheckFile("/storage/emulated/0/Pictures/Testing/checking.png");
doubleCheckFile.open(QIODevice::ReadWrite);
QPixmap checkingPixmap = QWidget::grab();
checkingPixmap.save(&doubleCheckFile);
doubleCheckFile.close();
This code does take a screenshot, but only of the button strip currently implemented, and not for the whole screen. I've also taken a 'screenshot' of just a white box with the screen's dimensions by using:
QDesktopWidget dw;
QWidget *screen=dw.screen();
QPixmap checkingPixmap = screen->grab();
Would anyone know of whether there was an alternative to using QScreen to take a screenshot in Android, or whether there's a specific way to get it working as compared to Windows? Or would QWidget be the right track? Any help's greatly appreciated!
as i can read in Qt doc : In your screenGrabber.cpp :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
replace with :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( 0 ); // as 0 is the id of main screen
If you want to take a screenshot of your own widget, you can use the method QWidget::render (Qt Doc):
QPixmap pixmap(widget->size());
widget->render(&pixmap);
If you want to take a screenshot of another app/widget than your app, you should use the Android API...

Using Cordova, is there a way to reference native icons?

I'm using Cordova 3.5 to build an app which contains a menu with pretty standard items in the list (home, contacts, etc.), and I want to use the native menu icons whenever possible. I believe those icons are already on the device as part of the OS, but I don't know if Cordova gives me a way to reference them.
I suppose I'd need to write a Javascript function to choose the right file name based on the platform, e.g.:
// this is pseudocode
var icon = '';
if (platform === 'android') {
icon = 'some/path/home.png';
} else {
icon = 'other/path/icon.home.png';
// or maybe a function such as the following exists:
// icon = cordova.getNativeIcon('icon.home.png');
}
$('.selector').css('background-image', icon);
Alternatively, I may be able to make do by referencing the files in CSS, e.g.:
.android .home-icon {
background-image: url('some/path/home.png');
}
.ios .home-icon {
background-image: url('other/path/icon.home.png');
}
So, how do folks handle this sort of thing in Cordova? Is there a function I can use to access native icons? Are folks just copying them into their projects? What's the best practice?
If you're working with Cordova, then you'll be working inside a web view provided by the host OS and you won't have direct access to any artwork. I've found that using icon fonts and CSS "themes" to work well enough, but that approach will replicate artwork already provided. There's extra work involved with theming for iOS 6 vs iOS 7 or 8, for example, but it's not as bad as it sounds.
IBM does have an article on partitioning your view between native and web controls, but it sounds a bit cumbersome. More details here: https://www.ibm.com/developerworks/community/blogs/worklight/entry/ios_combining_native_and_web_controls_in_cordova_based_applications

jQuery change event not firing on mobile when inside a function

Specifically, I'm seeing this issue on an Android tablet, but I'm told it's with ALL mobile devices -- iPhones, Nexus tablets, etc.
But I have the common problem of change events not firing. Here's the function code that has the click events assigned:
function do_this(with_this_data)
{
var that = this;
this.with_this_data = with_this_data;
this.period = 900;
this.updateHours();
$('#date').change(function() {
that.updateHours();
});
$('#time_hour').change(function() {
that.updateMinutes();
});
// extra irrelevant data trimmed out
}
Now...one fix that should work is to move those .change() statements into a $(document).ready block -- but the problem is, if I do, then i get all sorts of undefined variable issues and stuff....all of the "update" functions are within said $(document).ready block and defined by names like "FutureStuff.prototype.updateMinutes."
What are my options???
Mifeet, again, I appreciate your feedback; I know you weren't able to fully get me up and running, but I'm still thankful.
But anyway, I solved the issue...it meant that basically I had to rewrite a new version of the JS code and stick it in an "if this chap is using a mobile browser" block. So yeah, one huge block of code for desktop users, another for mobile...but it works. :) And it was a pain in the hiney.

Same Titanium code base for Android & Iphone

I have been trying to create a single codebase for both Iphone & Android for a intermediate level app. ( 4 tabs, multiple windows, maps etc.) using itanium 2.1 API.
However, I have found that things on Android platform dont work as smoothly or willingly as on Iphone epsecially tableviews & UI elemnts. The UI responsiveness on Android is also sluggish.
The kitchen sink examples are pretty straightforward. I am looking at an enterprise ready app which has to be maintained for atleast next couple of years.
Has anybody worked on similar lines with platform quirks and been successful in creating fully functional iOS & Android apps from SAME codebase?
I'm having a lot of success using the compile-time CommonJS mechanism for having a root view that then has os-specific capabilities.
For instance, my os-independent view might be ui/MyView.js :
var createAddButton = require("ui/MyView.AddButton");
var MyView = function() {
var self = Ti.UI.createWindow();
createAddButton(self, function() { alert('ADD!'); });
return self;
};
module.exports = MyView;
Then, I create os-specific functions to handle it:
iphone/ui/MyView.AddButton.js
module.exports = function(view, addHandler) {
var addButton = Titanium.UI.createButton({
systemButton: Titanium.UI.iPhone.SystemButton.ADD
});
addButton.addEventListener("click", addHandler);
view.rightNavButton = addButton;
};
android/ui/MyView.AddButton.js
module.exports = function(view, addHandler) {
view.activity.onCreateOptionsMenu = function(e){
var menuItem = e.menu.add({ title: "Add" });
menuItem.addEventListener("click", addHandler);
};
};
The CommonJS system they have implemented will pick the appropriate version of MyView.AddButton.js so that the button is added to the right place. It allows for the majority of the view to be the same, but the os-specific things to be separated properly.
Titanium is not meant for 1 codebase for all. You do need to rewrite stuff for every OS. However, some app developers claim to have reused 95% of its code. So only 5% of the code is OS specific. But I am sure their code is full with if-elses.
What I recommend doing, to be able to maintain it properly, without thousands of if-else constructions, is build a single backend core, and write code specifically for UI related matters per OS. This way, you have some UI related code for Android, UI related code for iOS and 1 core working for both.
Since Android and iOS differ a lot, writing a single codebase will make sure you can never use OS specific features (like android hardware menu button, or iOS NavigationGroup), and will let the UI look non-intuitive.

Categories

Resources