How to configure headless Chromedriver to emulate a device with hover? - selenium

In my application, some element should only be present when the device supports hover. Therefore, I use the following CSS:
#media(hover: none) {
#present-only-if-device-supports-hover {
display: none;
}
}
For testing this with Capybara, I’d like to emulate a device with hover. So far I could only get it working in non-headless mode.
I use the following check:
expect(page).to have_selector('#present-only-if-device-supports-hover', visible: true)
With driver :selenium_chrome, the check passes. However, with driver :selenium_chrome_headless, the check fails because the element is not visible.
(As a side note: Capybara::Node::Element#hover works with both drivers.)
I tried a few things which didn’t change this behavior:
I enabled device emulation with options.add_emulation(device_metrics: {width: 800, height: 800, pixelRatio: 1, touch: false}), as it seems like disabling touch enables hover. Indeed, changing :touch to true made it stop working in non-headless mode. But in headless mode, neither works.
I tried to set the webkit.webprefs.available_hover_types and webkit.webprefs.primary_hover_type preferences (which I found during a Chromium code inspection) to 1, but it didn’t have any effect. I also tried leaving off the webkit.webprefs. prefix.
More suggestions?

Try using Selenium-Profiles
It is undetected by companies like cloudfare and google.
For Emulation-settings, have a look at Example-profile

Related

WebdriverIO: Execution context is not available in detached frame

I'm trying to automate a flow that I've been doing at least once a day for the past 3 years. It's an unnecessarily convoluted process that is taking time out of my day. It's an internal proprietary system, so I can't give you any details about it, but suffice to say that I cannot change it. I have to try to automate it the way it is, and I'm stuck with the following error:
Execution context is not available in detached frame "https://..." (are you trying to evaluate?)
I'm using WebdriverIO with the default configuration, which uses Puppeteer internally. When I googled the error, I got a suggestion to add the following flags:
'--disable-web-security', '--disable-features=IsolateOrigins,site-per-process'
I did that, but it didn't help:
remote({
logLevel: 'trace',
capabilities: {
browserName: 'chrome',
'goog:chromeOptions': {
args: ['--disable-web-security', '--disable-features=IsolateOrigins,site-per-process']
}
}
})
I want to try it out in the REPL to do some more debugging, but I haven't figured out how to add those args when launching the REPL:
npx wdio repl chrome
Everything I've tried so far has failed. If someone knows how to do it, please let me know.
I don't do web automation normally and I chose WebdriverIO, since I have used it in the past for mobile automation. I'm wondering if this is a Puppeteer specific issue and if it would work in Selenium, but I'm not quite sure how to set that up. Puppeteer was just working out of the box.
Any guidance on how to get past this error would be greatly appreciated.
Turns out it was pretty simple:
browser.switchToFrame($('#iFrame'))
// Doing stuff inside the frame that causes the next page to show.
// Now that iFrame is gone and I have to switch out of it, to continue:
browser.switchToParentFrame()
// After the above call the execution context is not in a detached frame anymore.

Karate-UI Automation - How to close Location allowance window (Chrome)

I am using Karate-UI Automation Software. I run my test scenario under Chrome browser. When I go to page where map is displayed (e.g. Mapbox) user is asked about Location allowance (screenshot) with buttons Allow and Deny. Is there some easy trick to confirm/deny/close dialog in scenario step? - in feature file.
location allowance
Thank you for your advice.
Is this the Chrome dialog that does not impact the flow of the test but just stays there and is somewhat irritating ? I'm sorry I haven't found a way to suppress that. Would be great if someone can find a way, I have tried all the flags here, but none of them worked: https://peter.sh/experiments/chromium-command-line-switches/
We are experimenting with Karate-Robot to be able to handle some of these use-cases, but this is still experimental. We need people to try and contribute fixes, if you use this - take 0.9.6.RC1 because 0.9.5 has some issues.
Finally if you are facing a problem with plain HTML, please follow this process so that we can try and figure a solution or enhance the Karate syntax if needed: https://github.com/intuit/karate/tree/develop/examples/ui-test
It works perfectly if you use chromedriver. Refer below code snippet which currently I am using.
Background:
* def session = { capabilities: { alwaysMatch: { browserName: 'chrome', 'goog:chromeOptions': { args: [ '--disable-geolocation', '--test-type' ] } } } }
* configure driver = { type: 'chromedriver', port: 9515, executable: '<Path to chromedriver>', webDriverSession: '#(session)'}

PhantomJS not exactly rendering Sankey diagram HTML to PNG

I'm having trouble adjusting PhantomJS to create a PNG file that matches the original browser presentation.
Here is the entire sample html file. It's a sankey diagram creating using rCharts and d3-sankey. (You'll need to save the file to your hard drive and view it from there.)
I'm running on Windows and using rasterize.js:
>> phantomjs.exe rasterize.js test.html test.png
ISSUE: Below is a snip of one of the text strings when viewed in a browser:
And here is a snip of the same string from the PNG created by PhantomJS:
How do I make the text-shadow go away? I've played around with various CSS attributes (text-shadow) and webkit-specific attributes (e.g., -webkit-text-rendering), but can't seem to make it go away.
Is this a setting in PhantomJS? in the underlying webkit? or somewhere else?
rCharts has an undocumented function called take_screenshot that uses CasperJS (which in turn uses PhantomJS to take screenshots of rCharts created visualizations on a given html page.
For example, I forked the example you provided, renamed it as a html file, which you can view here.
I ran rCharts::take_screenshot('http://rcharts.io/viewer/?7063641'), which results in the following screenshot. The take_screenshot function uses system commands, and work well on a Mac. I have not tested it on Windows, so YMMV.
NOTE: You will need to install the dev branch for this feature.
OK - I found the issue. It is related to browser display differences. SANKEY.CSS sets the text shadow:
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
The text-shadow is ignored in Firefox (my default browser) and is properly rendered using Chrome (thanks #ramnath for cluing me into the browser differences!). PhantomJS uses webkit to render pages (which works properly) while Firefox uses gecko (which obviously doesn't implement text-shadow properly.) Fiddling with text-shadow in my original post didn't affect any changes - because Firefox wasn't rendering any changes and I was experimenting in the browser.
SO, the fix is to override .node text-shadow in my main HTML file. After the change, all is rendering as I prefer in the PhantomJS-created PNG.
.node text {
pointer-events: none;
text-shadow: 0 0px 0 #fff;
}
Lesson: to properly test HTML for rendering in PhantomJS on Windows, use Chrome to preview. Both use webkit as the underlying rendering engine.

Video.js controls come back on pause even though disabled

The subject pretty much says it all. I have a Video.js instance with controls turned off (aka no "controls" in the markup). It works brilliantly, but when I pause the video (using my external custom button and myPlayer.pause() the controls on the video fade back in. When I hit play, they fade out again.
This definitely doesn't seem like the way it should work. Does anyone know if this is a bug, or I'm just missing something?
ctangney's answer only works when using the uncompressed (dev) version of videojs, since once compressed the lockShowing method is renamed (so is player() for that matter). Hopefully his merge request for issue 556 will be accepted soon.
When lockShowing is called on pause() it adds the class vjs-lock-showing to the controls element, which has the css: display: block !important. This is causing the inline style of display:none, added by the disable() method, to be trumped. Here is work around which addresses the CSS specificity problem, and works with the compressed and uncompressed videojs:
var v = videojs("video", {});
if(!v.controls()) {
v.controlBar.el().className = v.controlBar.el().className + ' vjs-controls-disabled';
}
Then add to the bottom of the css file(s):
.vjs-controls-disabled {display: none !important;}
(Or you could just remove the !important from .vjs-lock-showing)
This is a confirmed bug. I see a proposed fix there, but it's still an open pull request at the moment. In the meantime you can fix this by just overwriting the ControlBar's lockShowing method.
var vid = videojs("video", {});
if (!vid.player().controls()) {
vid.controlBar.lockShowing = function(){};
}
... since (currently) the controlbar attaches a listener to 'pause' events and calls lockShowing().

Is it possible to render web content over a clear background using WebKit?

I'm trying to gauge the possibility of a patch to WebKit which would allow all rendered graphics to be rendered onto a fully transparent background.
The desired effect is to render web content without any background at all, it should appear to float over the desktop (or whatever is displayed behind the browser window).
Has anyone seen an app do this? (I can think of some terminal emulators that can.) If anyone has worked inside of WebKit (or possibly Gecko?) do you think it would be possible to do this?
Update: I've come to realize that Mac OSX dashboard widgets use this exact technique. So, this must be possible.
Update 2: I've compiled WebKit on linux and noticed the configure options include:
--enable-dashboard-support
enable Dashboard support default=yes
I'm getting closer. Can anyone help?
Update 3: I continue to find references to this in posts on various related mailing lists.
https://lists.webkit.org/pipermail/webkit-dev/2008-September/005019.html
https://lists.webkit.org/pipermail/webkit-dev/2009-June/008182.html
Solved!
Through ongoing research, scouring forums and source code repositories, I peiced together the necessary steps to accomplish this using only libwebkit and a standard compiz desktop (any Xorg desktop with compositing should do).
For a current libwebkit (1.1.10-SVN), there is an Ubuntu PPA:
deb http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main
deb-src http://ppa.launchpad.net/webkit-team/ppa/ubuntu jaunty main
As far as the code goes, the key is calling webkit_web_view_set_transparent.
And of course the system you're running it on should have a capable graphics card (intel, radeon, or nvidia) and be running a compositing window manager (like Compiz).
And finally, to actually see transparency, the content you're viewing must set a transparent background using CSS3, otherwise it's still completely opaque.
It's as simple as:
BODY { background-color: rgba(0,0,0,0); }
Here' is the full sample for the simplest possible webkit browser app, with transparency support:
#include <gtk/gtk.h>
#include <webkit/webkit.h>
static void destroy_cb(GtkWidget* widget, gpointer data) {
gtk_main_quit();
}
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
if(!g_thread_supported())
g_thread_init(NULL);
// Create a Window, set colormap to RGBA
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GdkScreen *screen = gtk_widget_get_screen(window);
GdkColormap *rgba = gdk_screen_get_rgba_colormap (screen);
if (rgba && gdk_screen_is_composited (screen)) {
gtk_widget_set_default_colormap(rgba);
gtk_widget_set_colormap(GTK_WIDGET(window), rgba);
}
gtk_window_set_default_size(GTK_WINDOW(window), 800, 800);
g_signal_connect(window, "destroy", G_CALLBACK(destroy_cb), NULL);
// Optional: for dashboard style borderless windows
gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
// Create a WebView, set it transparent, add it to the window
WebKitWebView* web_view = web_view = WEBKIT_WEB_VIEW(webkit_web_view_new());
webkit_web_view_set_transparent(web_view, TRUE);
gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(web_view));
// Load a default page
webkit_web_view_load_uri(web_view, "http://stackoverflow.com/");
// Show it and continue running until the window closes
gtk_widget_grab_focus(GTK_WIDGET(web_view));
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Back in Safari 1.3 and 2, there was a hidden debug menu (invoked via the Terminal: defaults write com.apple.Safari IncludeDebugMenu 1) that included a “Use Transparent Window” option.
http://www.macosxhints.com/article.php?story=20050418015445258
http://www.wiredatom.com/blog/2005/10/20/safari-transparency/
Not sure if this was a WebKit thing or a Safari thing though.
(In Safari 3, the debug menu seems to have been replaced by the “Develop” menu (enable in Preferences > Advanced) which doesn’t have the transparent window option.)
Basically you want to be setting the ARGB colour space to be sending to the window manager. Obviously only window managers that support compositing will be able to take advantage of this.
You might want to talk to the screenlet and compiz developers they should be able to help out more.
This gist works for me, as of 2013, tested only with ubuntu:
https://gist.github.com/pouria-mellati/7771779
I have a new solution which is really easy to do, for a single screenshot. It's using node.js with phantom.js library.
install node.js
run 'npm install -g phantomjs' in console/terminal
save the following as script.js and run it from console 'phantomjs script.js'
var page = require('webpage').create();
page.viewportSize = { width: 1920, height: 1500 };
page.open("http://www.theWebYouWantToRender");
page.onLoadFinished = function(status) {
page.evaluate(function() {
document.body.style.background = 'transparent';
});
page.render('render.png');
phantom.exit();
};
profit? :) enjoy