I am running Selenium Webdriver to test a web application that is under development (I have created quite a few tests so far). I have been trying to open a few new tabs in the window opened by Selenium but no success so far. I looked through quite a bit of different solutions but most of them for Java or Python and I'm using Javascript (I need to use Javascript).
Selenium Webdriver: v.3.1.0
OS: Xubuntu 16.04
Browsers: Chrome 55.0.2883.87 and Firefox 50.1.0
I have tried various solutions including:
action sequences, which do nothing in both Chrome and Firefox but complains in Firefox:
driver.actions().keyDown(Key.CONTROL).sendKeys('n').keyUp(Key.CONTROL).perform();
using Key.chord(), which results in no errors, no reaction but it does send the keys - Firefox giving a strange charCode after pressing the buttons
driver.findElement(By.css("body")).sendKeys(Key.chord(Key.CONTROL, 't'));
Key.CONTROL only, which also results in no errors, no reaction but it does send the keys - Firefox giving a strange charCode after pressing the buttons
driver.findElement(By.css("body")).sendKeys(Key.CONTROL + "t");
What I do at the moment is to navigate the driver to a website with javascript keypress detection and see if they were clicked after the 'aaa' :
driver.get("http://unixpapa.com/js/testkey.html");
driver.findElement(By.css("body")).sendKeys("aaa");
driver.findElement(By.css("body")).sendKeys(Key.CONTROL + "t");
This navigates to the page and it it oputputs that on the page detection area:
keydown keyCode=17 which=17 charCode=0
keydown keyCode=84 (T) which=84 (T) charCode=0
keypress keyCode=116 (t) which=116 (t) charCode=116 (t)
keyup keyCode=84 (T) which=84 (T) charCode=0
keyup keyCode=17 which=17 charCode=0
which I believe means that they have been clicked. However, there is no reaction and no tabs created. No error displayed anywhere, no complains. Nothing. I was not sure if this is a bug or a problem or something that I might not be doing right. So if anyone has any idea, please help.
To open new tab you can try to use
driver.executeScript('window.open();');
Try using following (Robot Class):
Robot robo = new Robot();
robo.keyPress(KeyEvent.VK_CONTROL);
robo.keyPress(KeyEvent.VK_T);
robo.keyRelease(KeyEvent.VK_CONTROL);
robo.keyRelease(KeyEvent.VK_T);
protected void openNewTab(String url) {
((JavascriptExecutor) driver).executeScript("window.open('" + url + "','_blank');");
}
use this method to open a new tab with a url
Related
I am testing the BroadcastChannel functionality and I'am having trouble. I open two Chrome windows and the dev tools for each. On the console I write:
const z = new BroadcastChannel('blarg')
z.onmessage = function (ev) {console.log(ev)}
I can examine z and it has the function saved to the onmessage prop so it all looks good. However, when I test:
z.postMessage('sweet')
in one of the consoles, nothing shows in the other. I would expect since both Chrome windows are subscribed to the broadcast channel blarg and have a function to console log the message that is posted, I would see the message sweet to be shown in the other console but nothing happens.
So two questions:
Can't I test BroadcastChannel interface in the devtools console like this?
If so, what am I missing about how BroadcastChannel works?
It works if:
the communication happens on the same origin
the channel name is the same on both ends (blarg in your case, but it could also be "")
you don't expect to receive the message if you are the sender
When you say
I open two chrome windows and the dev tools for each.
call them A and B. In nomenclature A and B are defined as "browsing contexts", and they could also be tabs, frames or iframes.
The following code is an example that satisfies conditions 1. and 2.
devtools A:
location.href = 'https://example.com'
z = new BroadcastChannel('blarg')
z.onmessage = (ev) => { console.log(ev) }
devtools B:
location.href = 'https://example.com'
z = new BroadcastChannel('blarg')
z.onmessage = (ev) => { console.log(ev) }
Condition 1 is also satisfied when browser contexts (windows, tabs, frames or iframes) don't "point" to any regular url (for example when you press CTRL+T to open a new tab). In this case the origin has the special value of chrome://new-tab-page.
Said that, if you post from A to B, B will receive the message and console.log it. The same applies vice versa.
I am trying to write an automated test program for one of my website using Selenium WEbDriver. I am having some problems when doing the test on Internet Explorer. The website that I am trying to test is built in AngularJS. I will explain my problems in detail.
Here, is the code that waits until Angular has finished processing.
private static ExpectedCondition angularHasFinishedProcessing() {
return (ExpectedCondition<Boolean>) driver -> {
String hasAngularFinishedScript = "var callback = arguments[arguments.length - 1];\n" +
"var el = document.querySelector('html');\n" +
"if (!window.angular) {\n" +
" callback('false')\n" +
"}\n" +
"if (angular.getTestability) {\n" +
" angular.getTestability(el).whenStable(function(){callback('true')});\n" +
"} else {\n" +
" if (!angular.element(el).injector()) {\n" +
" callback('false')\n" +
" }\n" +
" var browser = angular.element(el).injector().get('$browser');\n" +
" browser.notifyWhenNoOutstandingRequests(function(){callback('true')});\n" +
"}";
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
assert javascriptExecutor != null;
String isProcessingFinished = javascriptExecutor.executeAsyncScript(hasAngularFinishedScript).toString();
return Boolean.valueOf(isProcessingFinished);
};
}
private void waitForAngular() {
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(angularHasFinishedProcessing());
}
And here is the code that instantiates WebDriver for Internet Explorer.
System.setProperty("webdriver.ie.driver",
new File("H:/libraries/webdrivers/IEDriverServer.exe").getAbsolutePath());
DesiredCapabilities d = DesiredCapabilities.internetExplorer();
// To bypasse the Protected Mode settings of IE
d.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
driver = new InternetExplorerDriver(d);
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://arandomangularjsapp.com"); // Let's suppose this
I had to bypass the Protected Mode settings (shown in above code) because I was constantly getting this Exception
Caused by: org.openqa.selenium.WebDriverException: Unexpected error launching Internet
Explorer. Protected Mode must be set to the same value (enabled or disabled) for all
zones. (WARNING: The server did not provide any stacktrace information)
though I made sure that protected mode was enabled and same values were set for all zones.
Now comes the real issue I am having. Look at this block of code,
waitForAngular();
WebElement el = driver.findElement(By.xpath("//div[#class='events-list__event-info' and #id='48040']" +
"//following-sibling::div[#class='events-list__event-buy']/a"));
if(driver.toString().toUpperCase().contains("INTERNETEXPLORER"))
el.sendKeys(Keys.ENTER);
else
el.click();
waitForAngular();
webElement = driver.findElement(By.xpath("(//div[#class='ticket u-cf ng-scope'])[1]//select"));
select = new Select(webElement);
select.selectByIndex(1);
My first question, the way I am trying to wait for Angular app to get ready by calling waitForAngular(), is it a good way? In my program I even had to use Thread.sleep() so many times in order to let elements to properly render before I could invoke actions on them. It would be great if you guys can suggest me a proper way to use Selenium WebDriver along with Angular App.
Now let's talk about my second issue. I had to completely disable Protected Mode from Internet Explorer's options in order to run the program. Otherwise, I would get this exception,
Caused by: org.openqa.selenium.JavascriptException: JavaScript error in async script. (WARNING: The server did not provide any stacktrace information)
I get this exception when trying to execute waitForAngular(). What could be causing this? Is there any way by which I could keep the Protected Mode enabled and still be able to execute that script inside angularHasFinishedProcessing() method?
Finally, my third problem is related to click action not being triggered. Forget about the previous issues for a second. I disabled IE's Protected Mode, so my program starts IE without throwing any exception. The program successfully finds the first element as shown in the code above. But, the click action is not triggered, browser thus doesn't navigate to next page, and the program fails to find the second element. As a workaround I even tried el.sendKeys(Keys.ENTER); but it didn't work.** So, am I having this problem because I bypassed/disabled Protected Mode? Or, is there something else that I am not being able to see?**
I run tests on IE, Opera, Chrome and Firefox and the problem seems to occur only in IE. Any sort of help, suggestions or guidelines are highly appreciated.
Thank You.
I'm attempting to use the Skype javascript API and noticing some craziness: If my page is HTTP, everything works fine (all the skype buttons, and skype: protocol hrefs) but once I move it to HTTPS it breaks in Chrome, iPad, and iPhone. Case and point:
Call buttons work here:
http://developer.skype.com/skype-uris/skype-uri-tutorial-webpages#uriTJS_Generator
Call buttons DO NOT work here:
https://developer.skype.com/skype-uris/skype-uri-tutorial-webpages#uriTJS_Generator
This is on their own site and it's no workie...
Can anyone suggest some series of rain dances I should do to fix this? Praying to the Skype gods? I'm only a mere mortal.
On click script is creating iframe and adding src="skype:echo123;+16505550123?call" and then as mb21 said bug occurs or "restrictive security policy" happens.
function a(s, v, t) {
var u = true;
window.onblur = function () {
u = false
};
var r = document.getElementById(v);
if (r !== null) {
r.src = s //here error happens....
}
setTimeout(function () {
if (u) {
alert(Skype.installSkypeMsg);
Skype.tryAnalyzeSkypeUri("redirect", t);
window.location = Skype.SkypeClientDownloadUrl
}
}, 2000)
}
How about just using:
<a onclick="window.location='skype:echo123;+16505550123?call';return false;" href="">link</a>
I think this is a bug (or a quite restrictive security policy) in Chrome (and other browsers). In the Chrome developer console I get:
[blocked] The page at https://developer.skype.com/skype-uris/skype-uri-tutorial-webpages#uriTJS_Generator ran insecure content from skype:echo123;+16505550123?call.
It treats skype:echo123;+16505550123?call as a URL and finds it not to be secure (i.e. not https) so the browser refuses to load it. Probably, the JavaScript in the Skype SDK uses window.open or something similar, so digging around in their code might bring up a solution.
Maybe you can adapt this ugly workaround?
(works fine in Chrome on the iPhone)
I get this error:
TypeError: 'undefined' is not an object (evaluating 'win.location') in dg.js line 3
And the lightbox does not open.
The code in question inside PayPal's dg.js is:
startFlow: function (url) {
var win = that._render();
if (win.location) {
win.location = url;
} else {
win.src = url;
}
}
So does mobile Safari not understand that._render()? How do I get around this?
If it matters, I'm using Adaptive Payments, calling it like so:
var dg = new PAYPAL.apps.DGFlow({
trigger: null,
expType: 'light'
});
dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
I don't have any problems getting the payKey & the entire payflow works on desktops and in mobile browsers other than Safari (it works on desktop Safari). It also does not work when our site is run as an iOS web app, which I assume is just a shell for Safari anyway.
I can explain why you are seeing this error.
Safari on iOS only allows a window to be opened as a result of a user click/touch event.
The DGFlow._render() function executes:
window.open('', "PPDG");
which returns null if triggered by anything other than a user click/touch event.
I am guessing you are issuing an XMLHttpRequest to generate a PayRequest/PayKey on the server and then in the onsuccess callback you are calling DGFlow.startFlow().
The solution is two split the process into two steps:
When the user is ready to checkout, issue the call to the server to
generate the pay key.
Then, present the user with a button to Checkout with PayPal and when that is clicked, call DGFlow.startFlow()
Found a couple of ways to get around this...location.replace with the PayPal URL or using your own lightbox. I used easybox.
// Replace
dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
// with
var RUNNING_AS_WEB_APP = (window.navigator.standalone == true ? true : false);
if (RUNNING_AS_WEB_APP === false) {
dg.startFlow('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
} else {
location.replace('https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey);
// Or, lightbox option:
// $.easybox([{url: 'https://www.paypal.com/webapps/adaptivepayment/flow/pay?expType=light&payKey=' +data.paykey, width: 320, height: 480}]);
}
Try using the mini browser experience where expType=mini. Seems to work better than the lightbox on mobile devices.
Adaptive Payments without modal box or popups?
I am trying to use the Mozilla crypto object in JavaScript.
Here is my rather simple code in JavaScript:
$(document).ready(function() {
// Handler for .ready() called
register();
});
function onSmartCardChange() {
// window.location.reload();
console.log('insert-remove');
}
function register() {
window.crypto.enableSmartCardEvents = true;
document.addEventListener("smartcard-insert", onSmartCardChange, false);
document.addEventListener("smartcard-remove", onSmartCardChange, false);
console.log('version='+window.crypto.version);
}
The version of the crypto object is written in the console window.
But an event is not fired whenever I plug/unplug my USB gadget.
In ControlPanel/Device manager the smart card seems OK. I also installed Charismatics and Cryptovision software.
Why do not I get an event when I insert/remove the USB gadget?
Is it possible that something is wrong with my setup?
Thanks,
donescamillo#gmail.com
I had some luck. I added the device in Firefox/Tools/Options/encryption/SecurityDevices. Now When I restart Firefox, plug the reader, start Firefox, unplug reader, I get an event. In any other case (plugging in reader again, starting Firefox without reader and plugging reader in) I do not get an event.
Could the problem be in the DLL specified when I added the reader to Firefox?
Thank you
donescamillo#gmail.com