Excecuting an automated test on a website with selenium I was faced with this problem, that somewhere on the website, when my test changes the selection of a DropDownList, an alert-window is thrown asking "are you sure you want to leave this page".
The root problem is the refreshing times of the page. When I look for an element:
Select sortingDropDownlist= new Select(webdriver.findElement(By.id("sortView")));
it takes some time for the page to be refreshed, even if I hav not changed anything. In this case a thread.sleep(500) would help preventing an alert to be poped out.
After a change to the DropDownList:
sortingDropDownlist.selectByValue("alpha");
the onchange-javascript behind the list tries to reload the page, while my test is continuing to the Then-part verificating the new value. The test stucks there until someone manually closes the alert window. I get the error:
org.openqa.selenium.WebDriverException: unknown error: cannot determine loading status
from unexpected alert open
(Session info: chrome=53.0.2785.116)
(Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Windows NT 6.3 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 43 milliseconds
Build info: version: '2.53.1', revision: 'a36b8b1', time: '2016-06-30 17:37:03'
System info: host: 'de-adn-bfxqp72', ip: '192.168.99.1', os.name: 'Windows 8.1', os.arch: 'amd64', os.version: '6.3', java.version: '1.8.0_91'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={chromedriverVersion=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4), userDataDir=C:\Users\javadieh\AppData\Local\Temp\scoped_dir11488_27974}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=53.0.2785.116, platform=WIN8_1, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: b6e2d6fec84269128a420809f929916d
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
An easy but dirty solution is again to Thread.sleep(500) directly after changing the selection. But I have a bad feeling using thread.sleep. So I am looking for a good solution.
I also tried this solution: in a seperate thread waiting for an alert window to appear, switch to it and close it.
But... although the alert window ist there my thread does not find it. It is not a matter of time out. Here ist my thread's code:
public class AlertChecker extends Thread {
WebDriver webdriver=null;
WebDriverWait wait;
public AlertChecker(WebDriver webdriver) {
super();
this.webdriver = webdriver;
wait = new WebDriverWait(webdriver, 10);
}
public void run(){
System.out.println("MyThread running");
try {
wait.until(ExpectedConditions.alertIsPresent());
System.out.println("alert found");
Alert alert = webdriver.switchTo().alert();
alert.accept();
} catch (Exception e) {
//exception handling
System.out.println(e);
}
System.out.println("MyThread stopping");
}
}
How can I wait for the page to be refreshed?
Thanks.
If you are getting a JavaScript Alert please use the below code.
public static void isAlertpresent(WebDriver driver)
{
try
{
Alert window = driver.switchTo().alert();
String content = window.getText();
window.accept();
System.out.println("Alert Appeared & handeled : "+content );
}
catch (Exception e)
{
System.out.println("No Alert Appeared");
}
}
call this method from where you suspect the Alert is appearing as below,
isAlertpresent(driver);
If its not a JavaScript Alert, try Window handling techniques to handle the alert.
Related
my scenario is simple:i made a game using cocos2d-x and i want to download images (FB and Google play) for multi player users and show them once the download is done as texture for a button.
in ideal world, things work as expected.
things get tricky when those buttons got deleted before the download is done.
so the callback function is in weird state and then i get signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
and the app crashes
This is how i implmented it
I have a Layout class called PlayerIcon. the cpp looks like this
void PlayerIcon::setPlayer(string userName, string displayName, string avatarUrl){
try {
//some code here
downloadAvatar(_userName, _avatarUrl);
//some code here
}
catch(... ){
}
}
void PlayerIcon::downloadAvatar(std::string _avatarFilePath,std::string url) {
if(!isFileExist(_avatarFilePath)) {
try {
auto downloader = new Downloader();
downloader->onFileTaskSuccess=CC_CALLBACK_1(PlayerIcon::on_download_success,this);
downloader->onTaskError=[&](const network::DownloadTask& task,int errorCode,
int errorCodeInternal,
const std::string& errorStr){
log("error while saving image");
};
downloader->createDownloadFileTask(url,_avatarFilePath,_avatarFilePath);
}
catch (exception e)
{
log("error while saving image: test");
}
} else {
//set texture for button
}
}
void PlayerIcon::on_download_success(const network::DownloadTask& task){
_isDownloading = false;
Director::getInstance()->getScheduler()-> performFunctionInCocosThread(CC_CALLBACK_0(PlayerIcon::reload_avatar,this));
}
void PlayerIcon::reload_avatar(){
try {
// setting texture in UI thread
}
catch (...) {
log("error updating avatar");
}
}
As i said, things works fine until PlayerIcon is deleted before the download is done.
i dont know what happens when the call back of the download task point to a method of un object that s deleted (or flagged for deletion).
i looked in the downloader implementation and it doesn't provide any cancellation mechanism
and i'm not sure how to handle this
Also, is it normal to have 10% crash rate on google console for a cocos2dx game
any help is really appreciated
Do you delete de Downloader in de destructor of the PlayerIcon?
there is a destroy in the apple implementation witch is trigered by the destructor.
-(void)doDestroy
{
// cancel all download task
NSEnumerator * enumeratorKey = [self.taskDict keyEnumerator];
for (NSURLSessionDownloadTask *task in enumeratorKey)
{
....
DownloaderApple::~DownloaderApple()
{
DeclareDownloaderImplVar;
[impl doDestroy];
DLLOG("Destruct DownloaderApple %p", this);
}
In the demo code of cocos2d-x: DownloaderTest.cpp they use:
std::unique_ptr<network::Downloader> downloader;
downloader.reset(new cocos2d::network::Downloader());
instead of:
auto downloader = new Downloader();
It looks like you are building this network code as part of your scene tree. If you do a replaceScene/popScene...() call, while the async network software is running in the background, this will cause the callback to disappear (the scene will be deleted from the scene-stack) and you will get a SEGFAULT from this.
If this is the way you've coded it, then you might want to extract the network code to a global object (singleton) where you queue the requests and then grab them off the internet saving the results in the global-object's output queue (or their name and location) and then let the scene code check to see if the avatar has been received yet by inquiring on the global-object and loading the avatar sprite at this point.
Note, this may be an intermittent problem which depends on the speed of your machine and the network so it may not be triggered consistently.
Another solution ...
Or you could just set your function pointers to nullptr in your PlayerIcon::~PlayerIcon() (destructor):
downloader->setOnFileTaskSuccess(nullptr);
downloader->setOnTaskProgress(nullptr);
Then there will be no attempt to call your callback functions and the SEGFAULT will be avoided (Hopefully).
The sample code for perception simulation crashes my device. The device do respond to voice commands but there is not response to hand gestures neither no visuals. I have to use WDR to reset it everytime
Link to the documentation
https://learn.microsoft.com/en-us/windows/mixed-reality/perception-simulation
Here is the source code.
class Program
{
static void Main(string[] args)
{
Task.Run(async () =>
{
try
{
RestSimulationStreamSink sink = await RestSimulationStreamSink.Create(
// use the IP address for your device/emulator
new Uri("http://127.0.0.1:10080"),
// no credentials are needed for the emulator
new System.Net.NetworkCredential("snarain", "snarain"),
// normal priorty
true,
// cancel token
new System.Threading.CancellationToken());
IPerceptionSimulationManager manager = PerceptionSimulationManager.CreatePerceptionSimulationManager(sink);
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
// If main exits, the process exits.
Console.WriteLine("Press any key to exit...");
Console.ReadLine();
}
}
After a week of troubleshooting, I noticed the control mode switches to simulation that suspends all sensors to detect human gestures which makes the device unresponsive.
Switching it back to Default resolves this problem.
Solved !!
I am trying to run my test using Selenium and just encountered the problem. I have my test written for the Chrome browser. Now I have been trying to run the same tests in the Firefox browser, but they failed.
I've started to investigate the problem and found out that Firefox doesn't wait until page is fully loaded. Chrome works perfectly.
I am running Selenium in docker containers.
Here is my script
storeSearch(info) {
let that = this;
return new Promise(function (resolve, reject) {
browserClient.init()
.url("http://somewhere.com")
.selectByVisibleText("#store","Tech")
// Redirect to a new page
.setValue("input[name='search']", info.searchCriteria)
.selectByValue(".featured", 'MacBook')
.click("button[name='info']")
.element('.popup')
.then(function (element) {
if (element.state === 'success') {
}
});
});
}
It doesn't try even to select a store type from the select .selectByVisibleText("#store","Tech") and just throws an exception.
"An element could not be located on the page using the given search
parameters (\"input[name='search']\").",
I have tried to add timeouts but it doesn't work as well and gives me an error.
browserClient.init()
.url("http://somewhere.com")
.timeouts('pageLoad', 100000)
.selectByVisibleText("#store","Tech")
The following error is thrown.
"Unknown wait type: pageLoad\nBuild info: version: '3.4.0', revision:
'unknown', time: 'unknown'\nSystem info: host: 'ef7581676ebb', ip:
'172.17.0.3', os.name: 'Linux', os.arch: 'amd64', os.version:
'4.9.27-moby', java.version: '1.8.0_121'\nDriver info: driver.version:
unknown
I have been trying to solve this problem for two days, but no luck so far.
Could someone help, maybe you have some ideas what can cause the problem ?
Thanks.
UPDATE
.url("http://somewhere.com")
.pause(2000)
.selectByVisibleText("#store","Tech")
If I put some pause statements it works, but this is really bad and not what I expect from this framework. Chrome works perfectly. It waits until loading bar is fully loaded and only then performs actions.
The problem is in geckodriver I guess, I have tested it the same flow in Python, Java and the behavior is exactly the same.
I am experiencing the exact behavior you detailed above, all-green/passing test cases in Chrome, but on Firefox, a different story.
First off, never use timeouts, or pause in your test cases unless you are debugging. In which case, chaining a .debug() previously to your failing step/command will actually do more good.
I wrapped all my WDIO commands in waitUntill() and afterwards, I saw green in Firefox as well. See your code bellow:
storeSearch(info) {
let that = this;
return new Promise(function (resolve, reject) {
browserClient.init()
.url("http://somewhere.com")
.waitUntil(function() {
return browser
.isExisting("#store");
}, yourTimeout, "Your custom error msg for this step")
.selectByVisibleText("#store","Tech")
// Redirect to a new page
.waitUntil(function() {
return browser
.setValue("input[name='search']", info.searchCriteria);
}, yourTimeout, "Your custom error msg for this step")
.waitUntil(function() {
return browser
.selectByValue(".featured", 'MacBook');
}, yourTimeout, "Your custom error msg for this step")
.waitUntil(function() {
return browser
.click("button[name='info']");
}, yourTimeout, "Your custom error msg for this step")
.waitUntil(function() {
return browser
.isExisting(".popup");
}, yourTimeout, "Your custom error msg for this step")
.element('.popup')
.then(function (element) {
assert.equal(element.state,'success');
});
});
}
It's not pretty, but it did the job for me. Hopefully for you as well.
Enhancement: If you plan on actually building & maintaining a strong automation harness using WDIO, then you should consider creating custom commands that package the waiting & make your test cases more readable. See bellow an example for .click():
commands.js:
module.exports = (function() {
browser.addCommand('cwClick', function(element) {
return browser
.waitUntil(function() {
return browser.isExisting(element);
}, timeout, "Oups! An error occured.\nReason: element(" + element + ") does not exist")
.waitUntil(function() {
return browser.isVisible(element);
}, timeout, "Oups! An error occured.\nReason: element(" + element + ") is not visible")
.waitUntil(function() {
return browser.click(element);
}, timeout, "Oups! An error occured.\nReason: element(" + element + ") could not be clicked")
});
})();
All that's left to do, is import your module via require() in your test case file: var commands = require('./<pathToCommandsFile>/commands.js');
You can use code in javascript which will be waiting for state of website.
In C# looks like this:
public void WaitForPage(IWebDriver driver, int timeout = 30)
{
IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
}
I've run into quite a few issues like this with Selenium in Python and C#, unfortunately both in the Chrome and Firefox webdrivers. The problem seems to be that the code gets ahead of itself and tries to reference elements before they even exist/are visible on the page. The solution I found in Python at least was to use the Wait functions like this: http://selenium-python.readthedocs.io/waits.html
If there isn't an equivalent in node, you might have to code a custom method to check the source every so often for the presence of the element in x intervals over time.
The context :
On my mac app, when i click on a list item, a notification is sent to an object which does something in the background while on the UI there's a waiting message.
All of this takes place in a window which you can quit by a "Close" button. The button by default is disabled when the notifcation is sent.
What i a want to do is a timeout feature which allows the user to quit this windows after a couple minutes hence enabling the close button.
The code :
- (IBAction)onChangeOperator:(id)sender
{
[self performSelector:#selector(timerFired:) withObject:nil afterDelay:2.0];
....
....
//takes time
....
}
-(void) timerFired:(NSTimer *) theTimer {
[close_button setEnabled:YES];
}
The problem :
The button is not enabled until onChangeOperator is finished whereas i want it to be enabled as soon as selector is fired.
I think it's a thread thingy but i can't figure out.
From the documentation, performSelector:withObject:afterDelay:
Invokes a method of the receiver on the current thread using the default mode after a delay.
So the current thread is still blocked. You should instead run your expensive operation in onChangeOperator on a new thread:
- (IBAction)onChangeOperator:(id)sender
{
[self performSelector:#selector(timerFired:) withObject:nil afterDelay:2.0];
[self performSelectorInBackground:#selector(doUpdates) withObject:nil];
}
-(void) timerFired:(NSTimer *) theTimer
{
[close_button setEnabled:YES];
}
-(void)doUpdates
{
.... stuff that takes time....
}
My app is making heavy use of webservice calls. Lately, some of the calls got stuck. After playing around I figured out that it
happens mostly for release builds
happens in the Simulator AND on the device (iPad, iOS 4.3)
happens more often on iPad 1 than on iPad 2
it is not limited to web services an SOAP but also affects the System.Net.WebClient
does not affest [NSString stringWithContentsOfUrl:] if invoked manually, since not bound
The effect is that the CPU load of the device drops to zero. memory is stable (in my demo project 8.5MB). If I put Console.WriteLines() everywhere, I can see that the code is stuck inside one of the WebClient.Download*() methods.
The code below demonstrates that (if built RELEASE with MT 4.0.1, LLVM off or on does not matter) downloading a file from the web over and over again fails sometimes right away on the first try, sometimes after 10 times, sometimes after around 30 downloads.
It is totally random. If you think it works, kill the app and restart it and eventually it will hang.
When building the same using MT 3.2.6, the downloading goes on all day without issues. It is impossible to break it.
MONO installed is the latest available version.
Can somebody from the MT team comment on it?
using System;
using System.IO;
using System.Threading;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace iOSTest
{
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
private Thread oThread;
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// Make a release build and run on iPad 1 with iOS 4.3.2.
// Fails after downloading between 1 time and 30 times on MT 4.0.1.
// It is possible that it seems to work. Then just kill the app and restart and suddenly the effect
// will become visible. If you watch it with Instruments, CPU suddenly drops to zero. The app then is
// stuck somewhere inside WebClient. After about 10 minutes, an exception will be thrown (timeout).
// Never fails on MT 3.2.6
Console.WriteLine(MonoTouch.Constants.Version);
// A label that counts how often we downloaded.
UILabel oLbl = new UILabel(new System.Drawing.RectangleF(40, 100, 150, 30));
window.AddSubview(oLbl);
// This thread downloads the same file over and over again.
// The thread is not required to demonstrate the issue. The same problem occurs
// if the download is running on the main thread.
this.oThread = new Thread(delegate()
{
using(var oPool = new NSAutoreleasePool())
{
int i = 0;
while(true)
{
// Setup webclient and download a file from my website (around 2.4 MB)
WebClient oClient = new WebClient();
// It would be nice to hange it to your own URL to save me from all the traffic.
oClient.DownloadFile(new Uri("http://www.wildsau.net/image.axd?picture=2011%2f4%2fDSC05178.JPG"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "test.jpg"));
// Increase counter and update label.
i++;
this.InvokeOnMainThread(delegate { oLbl.Text = i.ToString(); });
Console.WriteLine("Done " + i + " times.");
}
}
});
// Have a button that starts the action.
UIButton oBtn = UIButton.FromType(UIButtonType.RoundedRect);
oBtn.SetTitle("Download", UIControlState.Normal);
oBtn.Frame = new System.Drawing.RectangleF(40, 40, 150, 30);
oBtn.TouchUpInside += delegate(object sender, System.EventArgs e)
{
this.oThread.Start();
};
window.AddSubview(oBtn);
window.MakeKeyAndVisible ();
return true;
}
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}
From Gonzalo-
When the problem occurs, "kicking" the threadpool by adding another
work item will make the problem go away.
Something like this (not tested or compiled ;-) should do:
Timer timer = new Timer (AddMe);
...
WebClient wc = new WebClient ();
Uri uri = new Uri(url);
timer.Change (0, 500); // Trigger it now and every 500ms
byte[] bytes = wc.DownloadData(uri);
timer.Change (Timeout.Infinite, Timeout.Infinite);
....
static void AddMe (object state)
{
// Empty.
}
#
Works 100% of the time - for me at least - YMMV. And it did, once we put the code under stress (Lots of files to download) it stalled again. Just heard from MT that 4.0.6 will have the fix in it. Should see it later this week!
Promised to be fixed by Xamarin in the next major release. Still does not work in 4.0.4 though.