I'm updating a Selenium program I wrote a while back and part of it has stopped working. I want to go through a whole series of links on a page, click on each, making sure that some expected text is present. But sometimes a log-in page (https://library.med.nyu.edu/sso/ezproxy_form.php) appears before the desired page, in which case I need to log in before checking the page. The problem is, no matter what string I put in to check whether I've landed on the log in page, Selenium concludes it's not present and skips logging in, obviously causing everything else to fail. See below--I'm not sure that was actually the problem. It seems to be instead that it's rushing through the "if we need to sign in" code without actually signing in, then obviously failing the main part of the test because it's not on the right page.
Here's the code--does anyone see my mistake?
for (int i = 0; i < Resources.size(); i++) {
try {
selenium.open("/");
selenium.click("link=" + Resources.get(i).link);
selenium.waitForPageToLoad("100000");
if (selenium.isTextPresent("Please sign in to access NYUHSL e-resources")) {
selenium.type("sso_user", kid);
selenium.type("sso_pass", password);
selenium.click("name=SignIn");
selenium.waitForPageToLoad("100000");
}
if (!selenium.isTextPresent(Resources.get(i).text)) {
outfile.println(Resources.get(i).name + " failed");
}
} catch (Exception e) {
outfile.println(Resources.get(i).name + " could not be found--link removed?");
}
}
Does the login page have a page title? If yes, try validating the page title using selenium.getTitle() method to check if you are headed to login page. If not, proceed clicking on the link without logging in.
I think page title validation can help resolve this issue
Try putting:
selenium.setSpeed("1000");
Right after the selenium.open this will inject 1 second delay (1000ms) between selenium commands. You should make it a standard practice to add this, especially if you're not running headless browsers.
Also you might consider using, since you know the url you are expecting to be on if on the login page, the selenium command getLocation. This will return the absolute URL of the current page. Might be more effective than trying to look for elements that can change at any time within the page.
So to use getLocation in your code above:
if (selenium.getLocation() == "your reference url"){
do your login stuff here
}
Again this is just a sample to illustrate what I'm saying. Hope it helps you out.
Related
EDIT: I'm using the LeanFT Java SDK 14.50
EDIT2: for text clarification
I'm writing test scripts for a web application that sometimes opens popup browsers for specific actions. So natually when that happens, I will attach the new browser using BrowserFactory.attach(...). The problem is that leanFT does not seem to have a way to validate that the browser exists before attaching it, and if I try to attach it too early, it will fail. And I don't like to use an arbitrairy wait/sleep time as I can never really know how much time it's going to take for the browser to get be ready. So my solution to this is below
private Browser attachPopUpBrowser(BrowserType bt, RegExpProperty url){
Browser browser = null;
int iteration = 0;
//TimeoutLimit.SHORT = 15000
while (browser == null && iteration < TimeoutLimit.SHORT.getLimit()) {
try {
Reporter.setReportLevel(ReportLevel.Off);
browser = BrowserFactory.attach(
new BrowserDescription.Builder()
.type(bt)
.url(url)
.build()
);
Reporter.setReportLevel(ReportLevel.All);
} catch (GeneralLeanFtException e) {
try {
Thread.sleep(1000);
iteration += 1000;
} catch (InterruptedException e1) {
}
}
}
return browser;
}
Now, this works wonderfully with one exception. It generates errors in the leanft test result. Errors that I want to ignore because I know that it will fail a few times before it will succeed. As you can see, I've tried changing the ReportLevel while doing this in order to suppress the error logging, but it doesn't work. I've tried using
Browser[] browsers = BrowserFactory.getallOpenBrowsers(BrowserDescription);
thinking that it will return an empty Array if it finds nothing, but I still get errors while the browser is not ready. Does anyone have suggestions as to how I could work around this?
TL;DR
I'm looking for a way to either suppress the errors generated within my While..Loop or to validate that the browser is ready before attaching it. All of that, so that I can have a nice and clean Run Result at the end of my test (because these errors will present false negatives in all nearly all of my tests)
Addendum
Also, when the attach fails for the first time, I get a an exception
com.hp.lft.sdk.ReplayObjectNotFoundException: attachApplication
as expected, but all subsequent failures are throwing
com.hp.lft.sdk.GeneralLeanFtException: Cannot read property 'match' of null
I've compared both stack traces and they are identical except for the last 2 lines which happen within the ReplayExceptionFactory.CreateDefault() so I think that there is something that gets corrupted during the exception generation, but that is within the leanft.sdk.internal package so there might not be a lot we can do about it right now.I'm guessing that if I did not get that second "cannot read property" exception, I would correctly get the ReplayObjectNotFoundException until the browser is correctly attached.
I'd rather not force an attach endlessly until it works. Even if we'd solve the false negatives, we'd still have a not so good approach to the problem.
The cleanest solution would be to see if there is anything to attach to in the first place.
And you can do just that by getting all the browser instances that meets your description.
Browser[] browsers = BrowserFactory.getAllOpenBrowsers(new BrowserDescription.Builder().build());
Any element in this collection is an already "attached" browser - you can start using it.
If the list doesn't contain your browser instance, rerun the query.
I have this funny bug happening to me today. I've been using Selenium for years already and never had an issue navigating to URL (via driver.navigate().to(url)) however today I'm attempting to navigate to a specific URL and I find that after executing the program several times it sometimes just stays on the original page without navigating to new page.
The funny thing is that this only happens about 50% of the time and it only happens when navigating to a specific URL at a specific part of the program (in other parts of program I have no issue navigating to this url).
Is it possible that some element on the current page is preventing driver.navigate().to(url) from executing?
I've looked at this and this question but both seem to have issues with navigating altogether. In my case, it sometimes works and sometimes doesn't (even when the exact same url is being used).
Also I'm not getting any specific errors (so I don't have much more info to post). The program just moves on as if the statement didn't exist.
I'll be happy to provide additional details if necessary.
Code:
shoppingCartURL.navToShoppingCart(driver);
String[] XPath = { "//*[contains (#value,'Delete')]" };
List<WebElement> elementList = webElementX.getElementListByXPath(driver, XPath);
System.out.println("Deleting " + elementList.size() + " element(s) from shopping cart");
for (int elementListCounter = 0; elementListCounter < elementList.size(); elementListCounter++) {
WebElement singleElement = elementList.get(elementListCounter);
try {
singleElement.click();
} catch (Exception e) {
System.out.println("Exception occurred (StaleElementReferenceException)");
}
}
if (conditionX == false) {
productPage.navToProductPage(driver, product); // this method is not always executed, program continues to execute productPage.performActionOnPage(driver); without navigating to 'product page'
productPage.performActionOnPage(driver);
}
public void navToProductPage(WebDriver driver, String product)
{
String URL = "https://www.example.com/product/" + product;
System.out.println("Navigating to " + URL); // always prints the correct url (but still doesn't always navigate to url as mentioned in question)
driver.navigate().to(URL);
}
Update:
I noticed ref=cart-ajax-error in redirect url (after deleting items from cart). Apparently, the site is using AJAX to refresh page after deleting items from cart. Might this conflict with my attempt to navigate to another page? In other words, perhaps Selenium is getting two different messages at the same time.. refresh page and navigate to new page.. so it remains on the current page?
If this is true, what can be done to resolve this issue?
Thanks!
When it sometimes happens and sometimes not it's nearly always a matter of timing.
Add an explicit wait to your code after navigating to the URL:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.urlToBe(URL));
I'm looking a way to call a detail page from master page composer.
I have following files :
src/main/webapp/po_inquiry.zul
src/main/webapp/po_inquiry_detail.zul
on click event of po_inquiry.zul grid, I need to redirect to po_inquiry_detail.zul
I found an article on https://www.zkoss.org/wiki/ZK_Developer's_Reference/UI_Patterns/Communication/Inter-Application_Communication
However, I still can't redirect into detail page. Here is the code for calling detail page. Called from master page Composer (selected data prints correct data on log, the error message is just ZK can't find /order/po_inquiry_detail.zul) :
#Listen("onDetail = #lstPoHeaders")
public void onDetail(ForwardEvent evt) {
PurchaseOrderHdr selectedData = (PurchaseOrderHdr) evt.getData();
Map<String, Object> params = new HashMap<String, Object>();
params.put(PurchaseOrderHdr.class.getName(), selectedData);
LOG.debug(selectedData);
Executions.createComponents("~/order/po_inquiry_detail.zul", getSelf().getParent(), params);
getSelf().detach();
}
I've also tried to put po_inquiry_detail.zul files under src/main/resources (classpath), but it didnt work too
Any help will be appreciated. Thank you
I think you make a mistake by reading that article.
That article is about multiple web apps and reaching out to pages of other apps.
Just try this :
Executions.createComponents("po_inquiry_detail.zul",getSelf().getParent(),params);
Now, a second mistake is that this is no redirection.
Redirection means, you will change the url, and in this case it will not happen.
Difference is seen in pressing F5 => you way will be the previous page and you will not see the detail.
Real redirection will show the detail page again.
I am trying to make a script for page, all I need is just simple java script, if there is a text on the page in example - no found the macros should hit the button find work. The macros must hit the button find work in 1 second interval.
Sorry for my english
This is an example how you could make JavaScript script for iMacros. The main part is CONTENT=EVENT:MOUSEOVER since that part hovers over a page element. If element is present it will return true else it will return false. Try it out.
var macroTest;
macroTest ="CODE:";
macroTest +="TAG POS=1 TYPE=INPUT:CHECKBOX FORM=NAME:TestForm ATTR=NAME:C9&&VALUE:ON CONTENT=EVENT:MOUSEOVER"+"\n";
if(iimPlay(macroTest)>0)
{
alert("Checkbox found");
}
else
{
alert("Checkbox not found");
}
I am creatin an app in Java that checks if a webpage has been updated.
However some webpages dont have a "last Modified" header.
I even tried checking for a change in content length but this method is not reliable as sometimes the content length changes without any modification in the webpage giving a false alarm.
I really need some help here as i am not able to think of a single foolproof method.
Any ideas???
If you connect the whole time to the webpage like this code it can help:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class main {
String updatecheck = "";
public static void main(String args[]) throws Exception {
//Constantly trying to load page
while (true) {
try {
System.out.println("Loading page...");
// connecting to a website with Jsoup
Document doc = Jsoup.connect("URL").userAgent("CHROME").get();
// Selecting a part of this website with Jsoup
String pick = doc.select("div.selection").get(0);
// printing out when selected part is updated.
if (updatecheck != pick){
updatecheck = pick;
System.out.println("Page is changed.");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Exception occured.... going to retry... \n");
}
}
}
}
How to get notified after a webpage changes instead of refreshing?
Probably the most reliable option would be to store a hash of the page contet.
If you are saying that content-length changes then probably the webpages your are trying to check are dynamically generated and or not whatsoever a static in nature. If that is the case then even if you check the 'last-Modified' header it won't reflect the changes in content in most cases anyway.
I guess the only solution would be a page specific solution working only for a specific page, one page you could parse and look for content changes in some parts of this page, another page you could check by last modified header and some other pages you would have to check using the content length, in my opinion there is no way to do it in a unified mode for all pages on the internet. Another option would be to talk with people developing the pages you are checking for some markers which will help you determine if the page changed or not but that of course depends on your specific use case and what you are doing with it.