I am currently testing a GWT web application similar to MS Paint and the problem which I am facing is that my test case passes on the browsers like Chrome, Firefox, and IE but sadly, it fails in the Microsoft Edge browser. I am unable to find out how to fix this issue after searching the whole Internet and trying out many methods which are written on the Stack Overflow and Google Groups, I am feeling extremely hopeless. Meanwhile, here is my code:
public class Insert_Element_in_Edge {
private static WebDriver driver;
#Test
public void main() throws InterruptedException, IOException
{
// TODO Auto-generated method stub
System.setProperty("webdriver.edge.driver", "D:\\SELENIUM\\Drivers\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.manage().window().maximize();
Thread.sleep(3000);
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
Thread.sleep(3000);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert = driver.findElement(By.xpath(InsertPath));
Thread.sleep(3000);
Insert.click();
}
}
Here's the error which I am facing:
org.openqa.selenium.ElementNotVisibleException: Element not displayed (WARNING: The server did not provide any stacktrace information)
Given below is the HTML code of the element which I am trying to locate in the Edge browser.
<div id="isc_2Q" eventproxy="isc_XXXIconButton_SClient_1" role="button" aria-label="xxx"
onfocus="isc.EH.handleFocus(isc_XXXIconButton_SClient_1,true);"
onblur="if(window.isc)isc.EH.handleBlur(isc_XXXIconButton_SClient_1,true);"
tabindex="1020" style="position: absolute; left: 0px; top: 54px; width: 40px;
height: 34px; z-index: 201152; padding: 0px; opacity: 1; overflow: visible;
cursor: pointer;" onscroll="return isc_XXXIconButton_SClient_1.$lh()" class="iconHoverZindex">
<div id="isc_2R"
eventproxy="isc_XXXIconButton_SClient_1" style="position: relative;
-webkit-margin-collapse: separate separate; visibility: inherit;
z-index: 201152; padding: 0px; cursor: pointer;">
<table role="presentation" cellspacing="0" cellpadding="0" width="40px" height="34px">
<tbody>
<tr>
<td nowrap="true" class="iconButton" style="background-color:transparent;"
align="center" valign="middle" onfocus="isc_XXXIconButton_SClient_1.$47()">
<img src="Insert Element.png" width="24" height="24" align="TEXTTOPundefined"
class="iconButtonHIcon" eventpart="icon" border="0"
suppress="TRUE" draggable="true"/>
<span style="vertical-align:middle;align-content:center;"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
This element is visible in other 3 browsers and is clicked successfully. But I just got stuck in Edge. Also, in Edge, the HTML5 canvas is also not displayed using Selenium. Please help.
You can add wait statement before click on it as given below.
wait.until(ExpectedConditions.ElementIsVisible(By.xpath(InsertPath)));
You have to use element to be clicable as it is a button
WebDriverWait wait = new WebDriverWait (driver, 50);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert= wait.until(ExpectedConditions.elementToBeClickable(By.xpath(InsertPath)));
Insert.click();
In the past I aslo had some trouble location elements with xPath in Edge, GWT and Selenium
Sadly I didnt found a solution but a workaround:
We gave every Element an ID
for example:
panel.getElement().setId("panel-id");
and then used the ID-Locator to find the Element:
findElement(By.id("panel-id"))
I read answers to your question that should solve your problem.
But noone asked you (and you did not provide us, in your question) informations about the version of your MicrosoftWebDriver, Selenium, and Browser that are you using.
From Microsoft WebDriver download, are you using a version that should be supported from your browser?
From EdgeHTML issue tracker, I found only 2 issues (that are fixed) with key element ElementNotVisibleException.
In these cases I usually take a screenshot just before the line where exception occurs and save it somewhere to further investigation. Then I mostly have to add a scrollUp()/scrollToVisible() function before this line to fix the problem.
I would suggest a few tweaks in your code block as follows:
First of all we will try to get rid of all the Thread.sleep(n) calls.
Now, to address the reason for ElementNotVisibleException, we will scroll the element of our interest within the Viewport and then invoke click() method.
Your final code block will may look:
driver = new EdgeDriver();
driver.manage().window().maximize();
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
WebElement Insert = driver.findElement(By.xpath("//div[#id='isc_2R']//td/img[#class='iconButtonHIcon' and contains(#src,'Insert Element.png')]"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Insert);
Insert.click();
Other than above suggestions,
Make sure that "Your Element" that you are looking for is physically visible in your Browser screen. Meaning, if element is not visible , user needs to scroll down in order to see it. Driver behaves similar. In order to prevent "ElementNotVisiable" exception make sure it is also visible on browser page
Try This,
Select elm = new Select(driver.findElement(By.Xpath("Your element's Absolute Xpath")));
//Thread.sleep(100);
elm.selectByValue("Dropdown Value which you want to select");
I've exactly the same problem with GWT. For any reason there's no way to call click directly.
Workaround that worked for me
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click()", element);
Related
I want to show a WebPage on another WebPage using InlineFrame.
I initialized it like this:
Wicket/ Java:
InlineFrame choosenTestcaseInlineFrame =
new InlineFrame("inlineFrame", AuthenticationPage.class);
public WhatToDoPage() {
Form whatToDoForm = configureWhatToDoForm();
add(whatToDoForm);
add(choosenTestcaseInlineFrame.setOutputMarkupId(true));
add(choosenTestcaseInlineFrame);
}
'
HTML:
<iframe wicket:id="inlineFrame" style="margin-left: 200px; height: 500px; width: 1000px">
The Problem is That the InlineFrame seems to refuse to show the Content.
here is a Screenshot:
I don't know if Chrome has a specific option to allow iframe to be displayed, but you might find some clues to solve the problem here:
iframe refuses to display
Dom structure :
<li class="slds-dropdown-trigger slds-dropdown-trigger--click slds-m-left--
x-small" data-aura-rendered-by="534:20;a">
<!--render facet: 537:20;a-->
<!--
render facet: 541:20;a--><button class="bare slds-button uiButton
forceHeaderButton oneUserProfileCardTrigger" aria-live="off" type="button"
data-aura-rendered-by="184:190;a" data-aura-class="uiButton
forceHeaderButton
oneUserProfileCardTrigger"><!--render facet: 185:190;a--><!--render facet:
187:190;a-->
<div class="tooltipTrigger tooltip-trigger uiTooltip" aria-describedby="tt-
for-174:190;a" tabindex="-1" data-aura-rendered-by="179:190;a" data-aura-
class="uiTooltip">
<span data-aura-rendered-by="171:190;a" class="uiImage"
data-aura-class="uiImage"><img data-aura-rendered-by="169:190;a"
src="https://c.ap5.content.force.com/profilephoto/005/T/1"
class="profileTrigger" alt="">
</span><span class="tooltip-invisible"
role="tooltip" id="tt-for-174:190;a" data-aura-rendered-by="181:190;a">View
profile</span>
</div></button><!--render facet: 543:20;a-->
</li>
i tried these lines of code for Logout :
First click on Logout symbol:
WebDriverWait wait3 = new WebDriverWait(driver, 20);
driver.findElement(By.xpath("//img[#class = 'profileTrigger']")).click();
JavascriptExecutor jse = (JavascriptExecutor)driver;
/*exe1.executeScript("arguments[0].click();", newbt);*/
jse.executeScript("scroll(250, 0)");
second click on Logout button :
driver.findElement(By.xpath("//a[#class =
'profile-link-label logout uiOutputURL']"));
I am getting error as Element is not clickable at point.
#SrieedherSanthakumar
I have few that would like to clarify first, whether or not are you dependent on wait call. Like you are clicking on something and want to wait for something and then process with your second click ?
If so, you might have to modify your first call something like below :
WebDriverWait wait3 = new WebDriverWait(driver, 20);
driver.findElement(By.xpath("//img[#class = 'profileTrigger']")).click();
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
JavascriptExecutor jse = (JavascriptExecutor)driver;
/*exe1.executeScript("arguments[0].click();", newbt);*/
jse.executeScript("scroll(250, 0)");
once you have waited for your page to be load or expected id is visible then proceed with your second call. I am not able to see whether you are waiting for your object in the first call to load since you are clicking on profileTrigger before moving forward with your second call.
1.Use scrollTo element by selector - this will ensure element is visible:
WebElement element = driver.findElement(By.xpath("//button[#class='oneUserProfileCardTrigger']"));
((JavascriptExecutor) driver)
.executeScript("arguments[0].scrollIntoView(true);", element);
2.Always use delay or wait after scroll before click. It takes time for browser.
3.If nothing helps - use javascript click. Bad solution as it not like real user do, but will work always:
WebElement element = driver.findElement(By.xpath("//button[#class='oneUserProfileCardTrigger']"));
((JavascriptExecutor)driver)
.executeScript("arguments[0].click();", element);
This is for an iframe injected into Gmail, I am unable to switch to this frame any help is highly appreciated.
HTML Code:
<iframe src="chrome-extension://fcinnggknmdfkilogcndkgpojpfojeem/src/iframe.html" id="Hiver_iframe_content" style="width: 100%; height: 263px; position: absolute; top: 60px; z-index: 4; border: none; display: none;"></iframe>
What I am trying to do :
driver.switchTo().frame("Hiver_iframe_content");
used to work perfectly fine a few days back..!!
This is not the way of switching frame what you are trying like
driver.switchTo().frame("Hiver_iframe_content");
You have to pass webElement or Index of frame while switching
Try this and let me know
driver.switchTo().frame(driver.findElement(By.id("Hiver_iframe_content")));
OR
driver.switchTo().frame(0); // 0 is index of frame
You can wait for the frame to load using explicit wait as given below.
WebDriverWait wait=new WebDriverWait(driver, 90);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("Hiver_iframe_conten"));
Try and let me know.
Thanks,
Murthi. S
try using switching to frame WebElement as below:
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe#Hiver_iframe_content")));
Appears that along with the release of New login for Gmail google released a new version of chrome driver , i fixed my issue by upgrading my chromedriver version
I found a way to switch to iframe which you mentioned. As a matter of fact there is not a single iframe but two iframes you have to switch. see the code below:
driver.switchTo().defaultContent();//First switch to default content
driver.switchTo().frame("Hiver_iframe_content");//Switch to 1st iframe
driver.switchTo().frame("iframe_handler");//Switch to 2nd iframe
P.s-This code now works for our automation and we're able to access v2 from iframe itself :-)
I am using Selenium Webdriver and working on automating an AngularJS Web App on Chrome. It was going pretty well until I hit a dropdown list on the app.
My test keeps crashing everytime I try to select a value from it. I have been doing my research on this and I have only seen 2 solutions (both of which I have tried but don't work)
Use the Select object. This doesn't work because the html tag is not <select>, its <md-select> and this fails the test.
I then tried to just click on the dropdown element and click on the value - driver.findElement(By.xpath("xpath to dropdown list")).click(); and driver.findElement(By.xpath("xpath do dropdown value")).click();
With example 2, I also tried creating it as a WebElement variable and calling click() separate, but this did not work either.
Any ideas on how I can solve this issue?
Update
HTML for the dropdown list
<div ng-switch-when="dropdown" class="ng-scope">
<zf-form-dropdown>
<div class="dropdown">
<div layout="row">
<div flex="50" class="quote-label">
<p ng-bind-html="::label" class="ng-binding">Title</p>
</div>
<div ng-show="false" flex="10" class="tooltip-icon ng-hide" ng-click="showToolTip(field.get('toolTip'))" role="button" tabindex="0" aria-hidden="true"><img src="img/item-question#2x.png"></div>
<md-select flex="" ng-disabled="quote.isRated() || !input.enabled" ng-change="onDropdownChange()" ng-model="input.value" class="ng-valid md-default-theme ng-touched ng-dirty" role="combobox" id="select_0Q9" aria-haspopup="true" aria-expanded="false" aria-labelledby="select_label_0I1" tabindex="0" aria-disabled="false" aria-invalid="false" aria-owns="select_menu_0Q8"><md-select-label class="md-select-label md-placeholder" id="select_label_0I1"><span></span><span class="md-select-icon" aria-hidden="true"></span></md-select-label></md-select>
</div>
</div>
</zf-form-dropdown>
</div>
HTML for the value I want to select
<md-option ng-value="::item.val" ng-selected="item.checked" ng-repeat="item in getOpts()" tabindex="0" class="ng-scope" role="option" aria-selected="false" id="select_option_0QD" value="MR">
<div class="md-text ng-binding">Mr</div>
<div class="md-ripple-container"></div>
</md-option>
The xpath for the dropdown list is //*[#id="select_0Q9"]
The xpath for the dropdown value is //*[#id="select_option_0QD"]
If you are sure that your Xpath is fine then you can also click using javascriptexecutor so try it out like below:-
WebElement element= driver.findElement(By.xpath("//md-option[#id='select_option_0QD']/div[1]"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Please feel free to locate the element in above code as per your convenience .
As per me your xpath of dropdown should be like below:-
//md-option[#id='select_option_0QD']
And xpath of first div which I suppose want to click is:-
//md-option[#id='select_option_0QD']/div[1]
Change [1] to [2] if you want 2nd value.
In an another aspect you can also store all your element in the list(As you know you can't use select) and click them as per your need or all.
For that you need to use xpath like:-
//md-option[#id='select_option_0QD']/div
Now implement it into code:-
List<WebElement> allelemts = driver.findElements(By.xpath("//md-option[#id='select_option_0QD']/div"));
for(WebElement ele: allelemts){
driver.findElement(By.xpath("//md-option[#id='select_option_0QD']")).click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", ele);
}
Hope it will help you :)
Since you are receiving a NoSuchElementException exception, I believe the issue lies in Selenium not able to identify the element. Try any of the following wait methods and then try to click the element.
Explicit Wait: (Most Preferred)
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("elementID")));
or
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("elementID")));
Implicit Wait:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Sleep: (Try to avoid this unless absolutely necessary)
Thread.sleep(1000);
EDIT: Added code to check for element's presence using findElements method.
Before using any of these wait methods you could also check for the presence of your element using findElements method.
List<WebElement> element = driver.findElements(By.id("elementId"));
if (element.size() == 0) {
System.out.println("Element not found");
} else{
System.out.println("Element found");
}
I have finally solved the issue!
I got the Selenium IDE and recorded a session where I got as far as selecting the dropdown menu and selecting my value. I then exported the file as a java test case and was able to read the lines where it selected the values, and they were;
driver.findElement(By.cssSelector("#select_08D > #select_label_005 > span.md-select-icon")).click();
driver.findElement(By.id("select_option_08H")).click();
So first off they both do not use xpath to find the elements, the dropdown menu itself is found with the cssSelector and the value is found by the id.
I am just cross referencing again and the id for the value is select_option_08H but while I am looking at Google Console I can see the id for the value is select_option_189
The input field for which I am trying to write the code in selenium:
input class="tt-hint" type="text" disabled="" spellcheck="off" autocomplete="off" style="position: absolute; top: 0px; left: 0px; border-color: transparent; box-shadow: none; background: none repeat scroll 0% 0% rgb(255, 255, 255);"
My code is:
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys(new String[] { "mo" });
But the above code does not work. The error I keep getting is:
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: Element is disabled and so may not be used for actions
Any help is appreciated.
I have modified my code to
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("mo");
I get the output as
The exception says it all. The element is not ready to accept any interaction and DISABLED. JavaScript is only option here. I would remove the disabled attribute and then use sendKeys()
String script = "document.getElementsByClassName('tt-hint')[1].removeAttribute('disabled')";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys("Whatever");
Javascript is the only option as said by #Saifur.However you do like this also
Either remove the disabled attribute or go with javascript to set the value itself
WebElement inp = driver.findElement(By.className("tt-hint"));
//Option 1 remove the disabled attribute
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("val");
//Option 2 go for javascript set value
js.executeScript("arguments[0].value=arguments[1]",inp,"val");
The below is the code for Selenium C#, for a hidden Textbox/TextArea
IWebElement element;
IJavaScriptExecutor js = (IJavaScriptExecutor)Driver;
js.ExecuteScript("arguments[0].value=arguments[1]", element, inputValueYouWantToPlace);
Some controls won't recognize the given text and gives error like 'please provide input value'- in this case Enable the element just before sending the value using SendKeys()
`
js.ExecuteScript("arguments[0].removeAttribute('disabled')", input);
js.ExecuteScript("arguments[0].click()", element);
element.SendKeys(inputValueYouWantToPlace);
`