I'm trying to automatize some test in order to open Jstree Nodes, using the Node name
I would like to make it clicking the arrow at the left of the node, instead of double-clicking the node itself.
Here is the code:
public void abrirSistema(String node) {
Boolean isPresent = driver.findElements(By.xpath("//*[contains(text(),'" + node + "')]")).size() > 0;
if (isPresent) {
System.out.println("System está abierto");
} else {
System.out.println("Hay que abrir el sistema");
WebElement system = driver.findElement(By.xpath("//*[contains(text(),'" + node + "')]"));
WebElement parent = system.findElement(By.xpath(".."));
String parentId = parent.getAttribute("id");
WebElement flecha = driver.findElement(By.xpath("//*[#id=\"" + parentId + "\"]/i"));
// WebElement arrow = parent.findElement(By.className("jstree-icon"));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
js.executeScript("arguments[0].scrollIntoView(true);", arrow);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
wait.until(ExpectedConditions.visibilityOf(flecha));
wait.until(ExpectedConditions.elementToBeClickable(flecha)).click();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
So basically I locate the Node by the name, cause elements on the tree changes dynamically, then pick the arrow, and click it.
The thing is that sometimes the code works, sometimes it doesn't, and I cannot figure it out why.
I make sure that page is full loaded before trying to run this, and when I run the Scenario, the step is always green although the Node is not opened
Also I would like to let you know that this code runs always after opening the root node, which is working properly. Just in case
Hope someone could help me.
Thanks in advance
Related
So this is my first question here after reading like hundreds of threads in this forum :D.
I want to click an HtmlAnchor with HtmlUnit and retrieve the underlying url.
Maybe I am using the wrong methods or something, but here is the code that I tried so far:
public List<String> clickURLs(String searchAttribute) {
try {
wc.getOptions().setCssEnabled(false); wc.getOptions().setJavaScriptEnabled(false); wc.getOptions().setUseInsecureSSL(true); wc.getOptions().setPrintContentOnFailingStatusCode(false); wc.getOptions().setThrowExceptionOnFailingStatusCode(false); wc.getOptions().setThrowExceptionOnScriptError(false);
HtmlPage page = wc.getPage(url);
List<HtmlAnchor> links =page.getAnchors();
for (HtmlAnchor link: links) {
if(link.getTextContent().contains(searchAttribute)) {
String href =link.click().getWebResponse().toString();
System.out.println(href);
list.add(href);
}
}
} catch (Exception e) {
System.out.println("An error occured: " + e);
} // catch
finally {
wc.close();
} // finally
return list;
} // clickURLs()
Any help would be appreciated.
I'm having an app which enables a customer to place an order for a ride (as in Uber), initially considered in a "WAITING" phase. When a driver accepts the order, it is automatically set in an "ACCEPTED" phase.
When ACCEPTED, the user is going to be redirected to another scene, telling him that he needs to wait for his rider to pick him up.
I decided to create a thread that checks every 250ms if the status of his order was set to ACCEPTED, like that:
public class AcceptanceRunnable implements Runnable {
private boolean running;
public AcceptanceRunnable() {
running = true;
}
public void run() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
// move to other scene
break;
}
} while(running);
}
public void setRunning(boolean running) {
this.running = running;
}
}
This AcceptanceRunnable class gets instantiated within the controller in the initialize() method:
#FXML
public void initialize() throws InterruptedException, IOException {
sourceAddress.setText("From: " + OrderSession.getOrder().getSourceAddress());
destinationAddress.setText("To: " + OrderSession.getOrder().getDestinationAddress());
price.setText("You'll need to pay RON " +
UserService.calculatePrice(UserSession.getUser()) + " for this ride.");
acceptanceRunnable = new AcceptanceRunnable();
Thread t = new Thread(acceptanceRunnable);
t.start();
}
Everything works fine. If I just print out some lines while waiting for the order's status to get changed, it seems to be okay. The problem is, I want my user to be redirected to another scene, if his order gets accepted.
This means, I need to insert something in place of the comment made in my AcceptanceRunnable.run() method.
I also tried changing the scene by having a method called ifAccepted() inside my controller, which actually triggers the method that changes the scene:
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
try {
Class<?> controller = Class.forName("com.example.yuber.controllers.CustomerWaitController");
Method ifAccepted = controller.getMethod("ifAccepted");
ifAccepted.invoke(controller.newInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
break;
}
But I only get some NullPointerException and I'm pretty sure that what I do here isn't really correct.
Any opinions?
As Slaw suggested, using Platform#runLater(Runnable) fixed my problem.
What I actually did was add my run() method from the Runnable inside my controller, renaming it to handleTread():
public void handleThread() {
do {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (OrderService.checkIfAccepted(OrderSession.getOrder())) {
Platform.runLater(() -> {
try {
SceneService.NewScene("/com/example/yuber/accepted-view.fxml", (Stage) rootPane.getScene().getWindow(), rootPane.getScene());
} catch (IOException e) {
e.printStackTrace();
}
});
break;
}
} while(running);
}
Not using Platform.runLater(...) would result in receiving a Not on FX Application Thread error.
Everything seems to be fine now.
I'm trying to use an element for testing and I want to continue the test if the element even couldn't be found.
I used NoSuchElementException for this part of my codes.
Here is what I've tried before:
try {
WebElement site_width_full_width = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("label[for=site_width-full_width]")));
site_width_full_width.click();
Thread.sleep(1000);
System.out.println("FullWidth Label Found!");
} catch (NoSuchElementException e) {
System.out.println("FullWidth Label not found!");
System.out.println(e);
}
But when the element isn't available it can't be thrown into the NoSuchElementException and all test breaks and fails.
What's the solution and how could I continue the test when the element isn't available.
Thanks in advance.
You might be getting the exception of a different derived class type. You can catch it using the parent class 'Exception' and then further drill down the exact exception type.
try using;
try
{
WebElement site_width_full_width = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("label[for=site_width-full_width]")));
site_width_full_width.click();
Thread.sleep(1000);
System.out.println("FullWidth Label Found!");
}
catch (Exception e)
{
if (e instanceof NoSuchElementException)
{
System.out.println("FullWidth Label not found!");
System.out.println(e);
}
else
{
System.out.println("Unexpected exception!");
System.out.println(e);
}
}
Hope this helps.
You can try with its parent classes like Throwable or Exception in catch block. In my case, I am Throwable in catch block which works as expected
You are catching a NoSuchElementException, but an explicit wait throws a TimeoutException if nothing is found. To get what you have working you should modify your code to do the following:
try {
WebElement site_width_full_width = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("label[for=site_width-full_width]")
));
site_width_full_width.click();
System.out.println("FullWidth Label Found!");
} catch (NoSuchElementException | TimeoutException e) {
System.out.println("FullWidth Label not found!");
System.out.println(e);
}
However using Try/Catch for execution flow is generally a code anti-pattern. You would be much better off doing something like this:
List<WebElement> site_width_full_width =
driver.findElements(By.cssSelector("label[for=site_width-full_width]"));
if (site_width_full_width.size() > 0) {
System.out.println("FullWidth Label Found!");
site_width_full_width.get(0).click();
} else {
System.out.println("FullWidth Label not found!");
}
Webdriver already provide the way to deal this problem in much simpler way. you can use following way
WebDriverWait wait= new WebDriverWait(driver, TimeSpan.FromSeconds(120));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException), typeof(ElementNotVisibleException));
WebElement site_width_full_width = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("label[for=site_width-full_width]")));
site_width_full_width.click();
Thread.sleep(1000);
System.out.println("FullWidth Label Found!");
Note : You can add all types of exception need to be ignored.
OS: Windows 7 32bit
ChromeDriver version: 2.30
Selenium Webdriver version: 3.4.0
Java 8
I've tried a few different ways to clean this code up and not have to repeat the same try/catch blocks. I'm trying to check that various elements are present on a page I'm testing. I can gracefully report to the console and this code does work with no problems.
The issue I'm having is with the ungraceful code. Is there a way to nest these try/catch blocks, or put them inside of an if/else loop?
try {
driver.findElement(By.xpath("/html/head/title"));
System.out.println("Title found...");
Thread.sleep(1000);
} catch (NoSuchElementException ex) {
System.out.println("Title NOT FOUND...");
// ex.printStackTrace();
}
try {
driver.findElement(By.xpath("//*[#id='logindiv']"));
System.out.println("Login form found...");
Thread.sleep(1000);
} catch (NoSuchElementException ex) {
System.out.println("Login form NOT FOUND...");
// ex.printStackTrace();
}
try {
driver.findElement(By.id("username"));
System.out.println("'Username' field found...");
Thread.sleep(1000);
} catch (NoSuchElementException ex) {
System.out.println("'Username' form NOT FOUND...");
// ex.printStackTrace();
}
try {
driver.findElement(By.id("password"));
System.out.println("'Password' field found...");
Thread.sleep(1000);
} catch (NoSuchElementException ex) {
System.out.println("'Password' form NOT FOUND...");
// ex.printStackTrace();
}
try {
driver.findElement(By.id("loginSubmit")).getText();
System.out.println("Login button found...");
Thread.sleep(1000);
} catch (NoSuchElementException ex) {
System.out.println("Login button NOT FOUND...");
// ex.printStackTrace();
}
A few things...
I'm a firm believer that exceptions should be exceptional, meaning exceptions shouldn't be used as flow control. This is further supported by the docs,
findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead.
so you should replace .findElement() and try-catch with .findElements() and test for empty. See example in #2.
You really should use some Assert library like JUnit, etc. It makes these validations so much easier/cleaner.
This whole thing
try
{
driver.findElement(By.id("username"));
System.out.println("'Username' field found...");
Thread.sleep(1000);
}
catch (NoSuchElementException ex)
{
System.out.println("'Username' form NOT FOUND...");
// ex.printStackTrace();
}
should/could look like
Assert.assertFalse(driver.findElements(By.id("username")).isEmpty(), "Validate Username field exists");
Arguments could be made that it's faster, so on and so forth but... it hurts me to see people use something complicated like an XPath to do no more than locate an element by ID, e.g. By.xpath("//*[#id='logindiv']"). This is so much simpler and easier to read as By.id("logindiv").
You can do some googling to see all the details but Thread.Sleep() is a bad practice and should be avoided. Instead use WebDriverWait. Explore ExpectedConditions to see all what can be waited for and use it liberally. In the cases you posted in your code, I don't see any reason to wait for any of these so that's several seconds of unnecessary wasted time.
Your last example is pulling .getText() but not using it. Since you are just checking that the button exists, you can safely remove the .getText() from the end.
You can try this:
public void checkElementVisibile()throws InterruptedException {
element = driver.findElement(By.xpath("/html/head/title"));
Thread.sleep(1000);
if(isElementVisibile(element))
System.out.println("Title found...");
else
System.out.println("Title not found...");
element = driver.findElement(By.xpath("//*[#id='logindiv']"));
Thread.sleep(1000);
if(isElementVisibile(element))
System.out.println("Login form found...");
else
System.out.println("Login form not found...");
element = driver.findElement(By.id("username"));
Thread.sleep(1000);
if(isElementVisibile(element))
System.out.println("'Username' field found...");
else
System.out.println("'Username' field not found...");
element = driver.findElement(By.id("password"));
Thread.sleep(1000);
if(isElementVisibile(element))
System.out.println("'Password' field found...");
else
System.out.println("'Password' field not found...");
}
public static boolean isElementVisibile(WebElement element){
try {
return element.isDisplayed();
}catch (NoSuchElementException ex)
{
return false;
}
}
A Robust Try Catch Method to use in WebDriver?
Can someone advice from there experiece whether the following method looks correct in the likely scenario where searching for an element gets timed out or the incorrect locator has been used?
The timeout Exception dosnt seem to be printing my System.out.println after i set the wait to 2seconds and change the locator with the wrong xpath
My Code:
public void clickSupercarsLink() throws Exception {
try {
this.wait.until(ExpectedConditions.elementToBeClickable(link_Supercars)).click();
} catch (TimeoutException e) {
System.out.println("UNABLE TO FIND ELEMENT : Timeout");
} catch (Exception e) {
System.out.println("UNABLE TO FIND ELEMENT : Exception");
throw (e);
}
}
New Code:
public void clickSupercarsLink() throws Exception {
try {
this.wait.until(ExpectedConditions.elementToBeClickable(link_Supercars)).click();
} catch (TimeoutException e) {
System.out.println("Timed out attempting to click on element: <" + link_Supercars.toString() + ">");
} catch (Exception e) {
System.out.println("Unable to click on element: " + "<" + link_Supercars.toString() + ">");
}
}
#Phil I would want you to throw that exception and handle it at high level. In current scenario, if there is a critical exception, your test will method calling your method clickSupercarsLink will not know that there was an exception.
Any way you are throwing exception, why do you have to catch it and do nothing with it then just printing!! This is not why you throw exception right?
public void clickSupercarsLink() throws Exception {
this.wait.until(ExpectedConditions.elementToBeClickable(link_Supercars)).click();
}