<table>
<tr>
<td>hi</td>
</tr>
</table>
<button id="change" onclick="change()">change</button>
<script>
function change(){
$("table").empty();
var $tr = $("<tr></tr>");
$tr.append( $("<td>bye</td>") );
}
</script>
WebDriver driver=new ChromeDriver(chromeOptions);
WebElement change= driver.findElement(By.id("change"));
change.click();
WebElement td=driver.findElement(By.xpath("//*table/tr/td[1]"));
System.out.println(td.getText());
I expected "bye", but it printed "hi".
How can I get dynamically changed text?
With the use of WebDriverWait explicit waits you can get the initial element text content. Then to wait for that text to no more be presented in that element after the click and then to get the new element text content. As following:
WebDriverWait wait = new WebDriverWait(webDriver, 20);
WebElement td =driver.findElement(By.xpath("//*table/tr/td[1]"));
String oldText = td.getText();
driver.findElement(By.id("change")).click();
wait.until(ExpectedConditions.not(ExpectedConditions.textToBePresentInElementLocated(By.xpath("//*table/tr/td[1]"), oldText)));
System.out.println(td.getText());
Related
I am trying to click an element that is not visible and needs to be scrolled down to be visible. To fix this, I have tried to use javascript executor and action, but they do not work because before even scrolling, I get a thread error saying the element is not visible. I have made sure that the xpath to the element is correct and verified the code works with elements that are visible without the need to scroll.
<div class="product-grid-item clearfix" data-alpha="LOG ON T-SHIRT BLACK" data-price="4800" data-i="27">
<a href="/products/8r9ya45zmdwz" class="product-link">
<img src="[//cdn.shopify.com/s/files/1/0923/4190/products/Palace-2019-Autumn-T-Shirt-Log-On-black-1336\_200x200\_crop\_center#2x.jpg?v=1565334138](//cdn.shopify.com/s/files/1/0923/4190/products/Palace-2019-Autumn-T-Shirt-Log-On-black-1336_200x200_crop_center#2x.jpg?v=1565334138)" alt="LOG ON T-SHIRT BLACK" class="img">
</a>
<div class="product-info">
<a href="/products/8r9ya45zmdwz" class="product-link">
<h3 class="title">LOG ON T-SHIRT BLACK</h3>
</a>
<div class="price">
<span class="prod-price">$48</span>
</div>
</div>
</div>
I have tried javascript executor and action
WebElement element = driver.findElement(By.xpath("//*[#data-alpha='" + productName + "' and #class='product-grid-item clearfix']")); //error occurs at this line
int elementPosition = element.getLocation().getY();
String js = String.format("window.scroll(0, %s)", elementPosition);
((JavascriptExecutor)driver).executeScript(js);
element.click();
and
WebElement element = driver.findElement(By.xpath("//*[#data-alpha='" + productName + "' and #class='product-grid-item clearfix']")); //error occurs at this line
Actions builder = new Actions(driver);
builder.moveToElement(element);
builder.click();
builder.build().perform();
Error message:
no such element: Unable to locate element: {"method":"xpath","selector":"//*[#data-alpha='WINDOWLICKER HOOD GREY MARL' and #class='product-grid-item clearfix']"}
Try use WebDriverWait and change the locator with contains, may contain space.
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[contains(#data-alpha,'" + productName.trim() + "') and #class='product-grid-item clearfix']")));
scroll here....
The element seems to be a dynamic element and as you mentioned that the element that is not visible and needs to be scrolled down to be visible so you can use either of the following solutions:
Using WebDriverWait and ExpectedConditions and elementToBeClickable():
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='product-grid-item clearfix' and contains(#data-alpha, 'LOG ON T-SHIRT BLACK')]//a[#class='product-link' and contains(#href, 'products')]/img[contains(#src, 'shopify')]"))).click();
Using WebDriverWait and ExpectedConditions and elementToBeClickable() through Actions:
new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[#class='product-grid-item clearfix' and contains(#data-alpha, 'LOG ON T-SHIRT BLACK')]//a[#class='product-link' and contains(#href, 'products')]/img[contains(#src, 'shopify')]")))).click().build().perform();
I have a selenium question if someone could help. I need to get into a URL page where initially a node on that page is in the "registered" status, and X amount of seconds later, its status will dynamically changed to "ready" status. And until its status has moved to "ready' status, I may continue the next steps during selenium execution.
Here is the html code of the initial code,
<div class="icon-holder pull-left" action = "select-device" sn="FX0071234" status = "in_stock">
<i class = "...">...</i>
<div class="model-holder">
<span class="model-registered">200K</span>
</div>
<div class="active-holder">...</div>
</div>
And here is the updated html code after X amount of seconds,
<div class="icon-holder pull-left" action = "select-device" sn="FX0071234" status = "discovered">
<i class = "...">...</i>
<div class="model-holder">
<span class="model-ready">200K</span>
</div>
<div class="active-holder">...</div>
</div>
I want to new a WebDriverWait() Obj to wait for the change happens. Here is my code:
new WebDriverWait(driver, 50).until(ExpectedConditions.attributeContains(
By.xpath("//span[#class = 'model-registered' and text() = '200K']"), "class", "model-ready"));
But during my selenium run-time, this piece of code never works, it exists instantly. Any ideas what could be wrong ? Thanks in advance.
To wait for the element to be changed to ready status you need to induce WebDriverWait and you can use the following solution:
boolean status = new WebDriverWait(driver, 20).until(ExpectedConditions.attributeContains(By.xpath("//div[#class='model-holder']/span[contains(.,'200K')]"), "class", "model-ready"));
You can directly wait for element with class "model-ready" to exists. Here's the code:
new WebDriverWait(driver, 50).until(ExpectedConditions.ElementExists(
By.xpath("//span[#class = 'model-ready' and text() = '200K']")));
Let me know if this doesn't works.
Use FluentWait to wait until status changes to 'Ready'.
Wait<WebDriver> wait = new FluentWait<WebDriver>(webDriver)
.withTimeout(30, TimeUnit.SECONDS) // set the timeout
.pollingEvery(2, TimeUnit.SECONDS); // set the interval. Checks every 2sec's for the element status 'ready'
WebElement foo = wait.until(new Function() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("//span[#class = 'model-ready' and text() = '200K']"));
}
});
You can also use the method waitForAttributeMatchesRegex to wait for the targeting attribute until it matches some specific pattern.
Something like this:
webElement.waitForAttributeMatchesRegex(attribute, regex);
I have an element on a website which looks like below
<div id="wrapperCategory" class="categoryItemWrapper">
<div class="panel panel-default panel-categoryItem text-center categoryItem disabledItem" ng-class="category.CategoryStyleClass" ng-click="setselectedProduct(productIndex,product,category); setselectedProductAmount(null);" title="Category">
<div class="panel-heading">
Category
</div>
<div class="panel-body">
Price
</div>
<div class="panel-footer availability" ng-class="category.AvailabilityStyleClass">
<span ng-bind-html="category.AvailabilityText">Avail</span>
</div>
</div>
</div>
I need to click on it to get forward. If I manually click on each of these divs or on span website goes forward but SeleniumWebdriver can't click any of them.
I tried click on span and on div with ng-click event buch each time i get an error:
Exception in thread "main" org.openqa.selenium.WebDriverException: Element <div class="panel panel-default panel-categoryItem text-center categoryItem" ng-class="category.CategoryStyleClass" ng-click="setselectedProduct(productIndex,product,category); setselectedProductAmount(null);" title="Category"></div> is not clickable at point (619.2666625976562, 474.23333740234375). Other element would receive the click: <div style="top: 0;left: 0;bottom: 0;right: 0;position: fixed;pointer-events: auto !important;z-index: 10000;" id="cover-1526454140024"></div>
I don't get it.
Can I somehow check which element is clickable and which element overlaps this which I want to click (I dont'see any div with id="cover-1526454140024" in code of the website) ?
Updated:
Unfortunately it still doesn't work after your solutions.
The same exception when trying to click.
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
JavascriptExecutor js = (JavascriptExecutor) Mundial.driver;
js.executeScript("arguments[0].scrollIntoView();", categoryItem);
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(categoryItem));
categoryItem.click();
List<WebElement> selects = driver.findElements(By.tagName("select"));
Select ticketsToSelect = new Select(selects.get(3));
ticketsToSelect.selectByValue("number:2");
It only works in case when I put sleep and scroll down manually. I don't get it.
As per your response :
You will have to scroll down to let the web element available to your script.For that you can use this code :
public static void scrollDown(WebDriver driver, String YoffSet){
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript(YoffSet);
}
here you can call this method anywhere from your code.
Then you can use this code to interact with the web element :
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("static ID")));
element.click();
I experienced lot of such issues, as Ankur says, use wait before click
WebElement seems_unclickable = wait.until(ExpectedConditions.elementToBeClickable(By.id(...
One of the way is ExpectedConditions commands
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("Yourid")));
More examples can be found at http://toolsqa.com/selenium-webdriver/wait-commands/
Try "scrollIntoView".
public void ScrollElementIntoView(IWebElement element)
{
var js = driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].scrollIntoView()", element);
}
I had the same issue and it was due to a having a non 100% zoom applied to the page body like:
body {
zoom: 90%;
}
Removing the css zoom fixed the issue.
This is the code which I was trying to execute.
driver.get("https://easemytrip.com/");
driver.findElement(By.id("ddate")).click();
driver.findElement(By.id("img2")).click();
I am unable to click on the next month of the calendar. Here is the HTML code.
<div class="month">
<div id="dvprevious" class="dvnxt" runat="server">
<img id="img2" onclick="return FillcalendarV(03,2017);" alt="Arrow" src="img/left.png"/>
</div>
<div class="month2">Apr 2017</div>
<div class="month3">
<img id="img1" onclick="return FillcalendarV(05,2017);" alt="Arrow" src="img/right.png"/>
</div>
</div>
My two work arounds were to force a mouse click on the item location.
WebElement elem = driver.findElement(By.id("id"));
Actions action = new Actions(driver);
action.moveToElement(elem).perform();
action.moveToElement(elem).click().perform();
or
driver.findElement(By.id("id")).sendKeys(Keys.ENTER);
The problem is that it takes a second for the calendar popup to get rendered so you need a brief pause. The next problem I ran into is that you apparently can't click the > img because it's blocked by the container DIV. So, I just clicked the container DIV and it worked. The code below works.
driver.get("https://easemytrip.com/");
driver.findElement(By.id("ddate")).click();
new WebDriverWait(driver, 3).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.month3"))).click();
Following code will work.
WebElement ele1 = driver.findElement(By.id("dvfarecal"));
ele1.click();
WebDriverWait wait = new WebDriverWait(driver, 5);
WebElement ele2 = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//img[#src='img/right.png']")));
ele2.click();
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
WebElement date = driver.findElement(By.id("snd_3_10/05/2017"));
date.click();
This is a continuation from my other post
Using JSoup to get data-code value of a table
I am trying to get the text inside the <span> tags on the table using the cssSelector() method in Selenium webdriver
<table class ="team-list">
<tr data-code="1">
<td>
<span>
Get This Text
</span>
</td>
</tr>
</table>
I have tried the following code, but this will print out the text in all cells for each row, but i only need to get the one inside the <span> tags
WebDriver driver = new FirefoxDriver();
driver.get("http://www.example.com");
List<WebElement> elements = driver.findElements(By.cssSelector("table.team-list td"));
for(WebElement element: elements)
{
System.out.println(element.getText());
}
if you know the text you are looking for you can the following:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.example.com");
List<WebElement> elements = driver.findElements(By.cssSelector("table.team-list td"));
for(WebElement element: elements)
{
if(element.getText().equals("Get This Text"))
System.out.println(element.getText());
}
That's might be o(n) but if you are not care about performance that could solve your problem.
I think you should change your selector to this:
By.cssSelector("table.team-list span")
Try something like this.
WebDriver driver = new FirefoxDriver();
driver.get("http://www.example.com");
List<WebElement> elements = driver.findElements(By.cssSelector("table.team-list td"));
for(WebElement element: elements)
{
try{
System.out.println(element.findElement(By.tagName("span")).getText());
}(org.openqa.selenium.NoSuchElementException nsee){
}
}