SeleniumWebdriver - Driver finds element but cant work on it? - selenium

I am trying to make a simple test to test the login form of a website. When I initialize the element Selenium finds it but if I try to click on it or check if its Displayed I either get an exception that the element is not visible or False for the Displayed.
The page: http://www.officemate.co.th/
My code:
IWebDriver driver = new ChromeDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("http://www.officemate.co.th");
IWebElement openSignUp = driver.FindElement(By.CssSelector("body > div:nth-child(6) > div > div:nth-child(3) > ul > li.dropdown > a"));
openSignUp.Click();
IWebElement usernameField = driver.FindElement(By.Id("UserId"));
usernameField.SendKeys("SomeUser");
Console.WriteLine(usernameField.Displayed);

try following code. i have tested it is working fine.
try
{
ChromeDriver driver = new ChromeDriver(#"C:\Users\Muhammad USman\Downloads\chromedriver_win32");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
//now i changed path for login.
driver.Navigate().GoToUrl("https://www.officemate.co.th/Account/Login");
//full specified xPath of eache element. is here whihc i'll use know.
//https://www.officemate.co.th/Account/Login
var email = #"/html/body/div[9]/div/fieldset/form/div[1]/div/input";
var password = #"/html/body/div[9]/div/fieldset/form/div[2]/div/input";
var check = #"/html/body/div[9]/div/fieldset/form/div[3]/div/input[1]";
var login = #"/html/body/div[9]/div/fieldset/form/div[4]/div/button";
IWebElement usernameField = driver.FindElement(By.XPath(email));
usernameField.Clear();
usernameField.SendKeys("SomeUser#gmail.com");
Console.WriteLine(usernameField.Displayed);
IWebElement pass = driver.FindElement(By.XPath(password));
pass.Clear();
pass.SendKeys("Some!password");
//Check box
var checkBox = driver.FindElement(By.XPath(check));
if (!checkBox.Selected)
{
checkBox.Click();
}
driver.FindElement(By.XPath(login)).Click();
if (driver.FindElements(By.XPath("/html/body/div[9]/div/fieldset/form/div[1]/p")).Count > 0)
{
//invalid login error message
var errorMessage = driver.FindElement(By.XPath("/html/body/div[9]/div/fieldset/form/div[1]/p")).Text;
}
}
catch (Exception exp)
{
throw;
}
if any issue then let me know.
Thanks.

Related

VB.NET Selenium question about webdriverwait to wait for specific element been load by browser

I have trying so hard to search how to wait for specific element been load to the browser.
However, most of code are in python and C#, I am trying to convert but still cannot.
I cannot find ExpectedConditions please let me know which reference I need to imports, because I keep looking for is expectedCondidtion in namespace still cannot find it.
Can anyone share a code or link that how to use webdriverwait? because I still cannot understand.
I want to do is wait a element been load to the browser, and if element not in page will do something else.
Now I using is try and catch but, sometime internet slow cannot really wait for page fully load, direct show the exception of elelment is not in page.
Code :
WebDriverWait wait = new WebDriverWait(getDriver(), timeOut);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("MainContent_lblLandmarkUPRN")));
You can use below function to wait until element is visible
public static IWebElement WaitforElement(this IWebDriver driver, By by, int timeoutInSeconds = 5, bool checkIsVisible = false)
{
IWebElement element;
driver.Sync();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.IgnoreExceptionTypes(typeof(StaleElementReferenceException));
try
{
if (checkIsVisible)
{
element = wait.Until(ExpectedConditions.ElementIsVisible(by));
element = wait.Until(ExpectedConditions.ElementToBeClickable(by));
}
else
{
element = wait.Until(ExpectedConditions.ElementExists(by));
}
}
catch (NoSuchElementException) { element = null; }
catch (WebDriverTimeoutException) { element = null; }
catch (TimeoutException) { element = null; }
catch (StaleElementReferenceException) { element = null; }return element;
}

selenium webdriver with variable

Trying to pass the defined variable to element selector, I tried few options, but it didn't work. Can anyone help me ?
def test_04(self):
driver = self.driver
spreadsheet =
pd.read_excel('SCC_ProdEdit_Page_Top80_Usage_ControlIds.xlsx',
sheetname='Prod_Edit_Page')
usernameField = spreadsheet['ControlID'][0]
username = spreadsheet['ControlID'][1]
passwordfield = spreadsheet['ControlID'][2]
password = spreadsheet['ControlID'][3]
login = spreadsheet['ControlID'][4]
print(usernameField)
print(username)
print(passwordfield)
print(password)
print(login)
self.driver.get("https://stagenext-scc3.foodchainid.com/Login")
driver.maximize_window()
driver.find_element_by_id(%s username?? ).send_keys(username ??)
driver.find_element_by_id(%s username?? ).send_keys(username ??)
I accomplish this by using two different methods, but they require your elements to be unique. I am assuming that in the HTML the ID of the username field is username (id="username")
WebElement targetElement = getElementWithId(driver,"username");
public static WebElement getElementWithId(final SearchContext context, final String idValue) {
WebElement targetElement = null;
targetElement = getElementByLocator(context, By.id(idValue));
return targetElement;
}
public static WebElement getElementByLocator(final SearchContext context, final By locator) {
WebElement targetElement = null;
try {
targetElement = context.findElement(locator);
} // catch selenium exceptions so that the action can act upon the result of the try action.
catch (final NoSuchElementException e) {
} catch (final ElementNotFoundException e) {
} catch (final ElementNotVisibleException e) {
}
return targetElement;
}
If I'm understanding it right, you are are not able to pass a variable to find_element_by_id method and send_keys method.
You dont have to use %s. You can directly use the variable name instead as find_element_by_id(username).
Below code worked for me,
usernameFieldID = "userName" #spreadsheet['ControlID'][0] This is the id for your username field and only one element exists with this id
username = "test-user" #spreadsheet['ControlID'][1] This as the value (actual username) you have to enter in the user name field.
self.driver.get("https://stagenext-scc3.foodchainid.com/Login")
time.sleep(5) # Just to make sure that the page has loaded before I search for elements. Not relevant to your question.
driver.maximize_window()
driver.find_element_by_id(usernameFieldID).send_keys(username)
If this did not solve you issue, please consider adding more details about the error you are facing.

Can we retrieve text/drag n drop elements using JavascriptExecutor similarly we are doing with gettext/Actions in Selenium

In below code if the my div containing the attribute as text then only it will return the text. I am new/curious to find new way to use JavascriptExecutor instead of selenium as they are much faster than selenium
WebElement gettexxxt= driver.findElement(By.id("loginButton"));
JavascriptExecutor executor1 = (JavascriptExecutor) driver;
String text = (String) executor1.executeScript("return arguments[0].text;", gettexxxt));
System.out.println(text);
Right now I am retrieving the text as below using JavascriptExecutor
WebElement Rent_rentc =(WebElement) ((JavascriptExecutor) driver).executeScript("return document.getElementById('loginButton');");
System.out.println(Rent_rentc.getText());
Is there any way to get text using JavascriptExecutor except above solution?
Note:- I am editing this question as I got the answer of how to gettext from JavascriptExecutor by referring Vicky answer in this page. Please refer from here to answer my next problem that how we can perform drag and drop using JavascriptExecutor.
I am facing error in below code, Error :- No match found
driver.get("https://jqueryui.com/droppable/");
WebElement iframe=driver.findElement(By.xpath(".//*[#id='content']/iframe"));
driver.switchTo().frame(iframe);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
try{
String filePath = "./dnd.js-master//dnd.js";
String source = "div[id='draggable']";
String target = "div[id='droppable']";
StringBuffer buffer = new StringBuffer();
String line;
BufferedReader br = new BufferedReader(new FileReader(filePath));
while((line = br.readLine())!=null)
buffer.append(line);
Pattern pattern = Pattern.compile("'(.*?)'");
Matcher matcherSource = pattern.matcher(source);
Matcher matcherTarget = pattern.matcher(target);
String cssSource = "#" + matcherSource.group(1);
String cssTarget = "#" + matcherTarget.group(1);
String javaScript = buffer.toString();
javaScript = javaScript + "$('" + cssSource + "').simulateDragDrop({ dropTarget: '" + cssTarget + "'});";
((JavascriptExecutor)driver).executeScript(javaScript);
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
}
Another code error :- expected expression, got '.'
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://jqueryui.com/droppable/");
String line = null;
String source = ".//*[#id='draggable']";
String target = ".//*[#id='droppable']";
try{
BufferedReader br = new BufferedReader(new FileReader("./dnd.js-master//Drag.js"));
StringBuffer buffer = new StringBuffer();
while((line = br.readLine())!=null)
buffer.append(line);
String javaScript = buffer.toString();
Thread.sleep(5000);//you can remove it added just to show you that drag and drop appeared as it is too fast
String java_Script = javaScript + "$("+source+").simulateDragDrop({ dropTarget: "+target+"});";
((JavascriptExecutor)driver).executeScript(java_Script);
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
Use the below Javascript to get the text of the Element
String Rent_rentc =(String) ((JavascriptExecutor) driver).executeScript("return document.getElementById('loginButton').getElementsByTagName('div')[0].innerHTML;");
Also, I want to know can we perform drag and drop using
JavascriptExecutor
A working example using the above javascript library is already posted in stackoverflow
Note:- I am editing this question as I got the answer of how to
gettext from JavascriptExecutor by referring Vicky answer in this
page. Please refer from here to answer my next problem that how we can
perform drag and drop using JavascriptExecutor.
I am facing error in below code, Error :- No match found
EDIT :
(function ($) {
$.fn.simulateDragDrop = function (options) {
return this.each(function () {
new $.simulateDragDrop(this, options);
});
};
$.simulateDragDrop = function (elem, options) {
this.options = options;
this.simulateEvent(elem, options);
};
$.extend($.simulateDragDrop.prototype, {
simulateEvent: function (elem, options) {
/*Simulating drag start*/
var type = 'dragstart';
var event = this.createEvent(type);
this.dispatchEvent(elem, type, event);
/*Simulating drop*/
type = 'drop';
var dropEvent = this.createEvent(type, {});
dropEvent.dataTransfer = event.dataTransfer;
this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);
/*Simulating drag end*/
type = 'dragend';
var dragEndEvent = this.createEvent(type, {});
dragEndEvent.dataTransfer = event.dataTransfer;
this.dispatchEvent(elem, type, dragEndEvent);
},
createEvent: function (type) {
var event = document.createEvent("CustomEvent");
event.initCustomEvent(type, true, true, null);
event.dataTransfer = {
data: {
},
setData: function (type, val) {
this.data[type] = val;
},
getData: function (type) {
return this.data[type];
}
};
return event;
},
dispatchEvent: function (elem, type, event) {
if (elem.dispatchEvent) {
elem.dispatchEvent(event);
} else if (elem.fireEvent) {
elem.fireEvent("on" + type, event);
}
}
});
})(jQuery);
save the above jquery to a file ex:Drag.js
driver.get("http://the-internet.herokuapp.com/drag_and_drop");
String line = null;
BufferedReader br = new BufferedReader(new FileReader("/path/Drag.js"));
StringBuffer buffer = new StringBuffer();
while((line = br.readLine())!=null)
buffer.append(line);
String javaScript = buffer.toString();
Thread.sleep(5000);//you can remove it added just to show you that drag and drop appeared as it is too fast
String java_Script = javaScript + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});";
((JavascriptExecutor)driver).executeScript(java_Script);
}
please explain how it will work with the same div contain the or child
div will contains many similar attribute like div
<button id="loginButton">Submit<button>
document.getElementById('loginButton') //will find the first element with id loginButton
<a id="loginButton" class="initial" href="javascript:void(0)" onclick="pageController.submitForm(); return false;"><div>Login </div></a> <div>Login </div>
document.getElementById('loginButton').getElementsByTagName('div')[0]; //will find the first element with id loginButton and then first div child inside it
<a id="loginButton" class="initial" href="javascript:void(0)" onclick="pageController.submitForm(); return false;"><div>Login </div><div>Register</div></a>
document.getElementById('loginButton').getElementsByTagName('div')[1]; //will find the first element with id loginButton and then second div child inside it
<a id="loginButton" class="initial" href="javascript:void(0)" onclick="pageController.submitForm(); return false;"><div><div>Register</div></div></a>
document.getElementById('loginButton').getElementsByTagName('div')[0].getElementsByTagName('div')[0].innerHTML;//will find the first element with id loginButton and then first div child inside it and then locate the first div child inside it
//you can also use other attributes like document.getElementsByClassName
Can you please provide me some links also where from I can refer/learn
the formatting of the JavascriptExecutor
W3schools
Hope this helps you.Kindly get back if it is not working

How to check items of the context menu, after right click, Selenium?

I'm writing a test(using selenium) to verify that after a i right click on a particular part of our website, it should show the standard context menu (copy, past, reload, saveAs etc) and not our created context menu.
I need to find a way to check the items on the context menu after the right click, any ideas?
Heres where i am so far...
private IWebDriver driver = null;
private WebDriverWait wait = null;
private Actions action;
[TestInitialize()]
public void Initialize()
{
driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://localhost/testwebportal");
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
action= new Actions(driver);
}
[TestMethod]
public void Right_click_brochure_while_zoomed_in_ID_8_2()
{
// click brochure
var clickFirstProduct = driver.FindElement(By.CssSelector("div.MetaSearchBrochureTile:nth-child(1) > div:nth-child(1) > img:nth-child(2)"));
clickFirstProduct.Click();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(1500));
// zoom in
var brochurePage = driver.FindElement(By.CssSelector(".p1"));
brochurePage.Click();
action.ContextClick(brochurePage);
// code to check if context menu is not my created right click menu browser,
// by looking at the menu items after the right click.
action.Perform();
}
Ray
If you are looking for the machinary to drive a selenium right click, check out how to do a right click in selenium or how to simulate a right click with code in selenium.
I hope this helps. If I have miss understood your question please let me know. Since you did not give me the HTML structure I have made many assumptions.
ContextOption is an array of string with contains the options expected in the context menu.
What I am doing is comparing the options expected with the optionsdisplayed in the context menu by text. This will return false if any one them is mismatched, less than what you expected or more than what you expected
Please remember to replace the code with proper element locaters.
var actions = new Actions(driver);
WebElement webElement = driver.FindElement(By.XPath("")));
actions.ContextClick(webElement).Perform();
int numberOfOptionPresent = 0;
foreach (var option in ContextOption)
{
IWebElement contextOptions = driver.FindElement(By.XPath(""));
ReadOnlyCollection<IWebElement> totalContextOption = contextOptions.FindElements(By.TagName("li"));
for (int c = 1; c <= totalContextOption.Count; c++)
{
string contextText = driver.FindElement(By.XPath("li[" + c + "]")).Text;
if (contextText == option)
{
if (contextText != "")
{
numberOfOptionPresent++;
}
break;
}
if (totalContextOption.Count == c)
{
return false;
}
}
if (numberOfOptionPresent == ContextOption.Count())
{
return true;
}
return false;
}

How to deal with ModalDialog using selenium webdriver?

I am unable to switch to Modal Dialog of given example
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/showModalDialog2.htm
I don't know how to get element on modal Dialog
Use
following methods to switch to modelframe
driver.switchTo().frame("ModelFrameTitle");
or
driver.switchTo().activeElement()
Hope this will work
What you are using is not a model dialog, it is a separate window.
Use this code:
private static Object firstHandle;
private static Object lastHandle;
public static void switchToWindowsPopup() {
Set<String> handles = DriverManager.getCurrent().getWindowHandles();
Iterator<String> itr = handles.iterator();
firstHandle = itr.next();
lastHandle = firstHandle;
while (itr.hasNext()) {
lastHandle = itr.next();
}
DriverManager.getCurrent().switchTo().window(lastHandle.toString());
}
public static void switchToMainWindow() {
DriverManager.getCurrent().switchTo().window(firstHandle.toString());
Try the below code. It is working in IE but not in FF22. If Modal dialog found is printed in Console, then Modal dialog is identified and switched.
public class ModalDialog {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
WebDriver driver = new InternetExplorerDriver();
//WebDriver driver = new FirefoxDriver();
driver.get("http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/showModalDialog2.htm");
String parent = driver.getWindowHandle();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement push_to_create = wait.until(ExpectedConditions
.elementToBeClickable(By
.cssSelector("input[value='Push To Create']")));
push_to_create.click();
waitForWindow(driver);
switchToModalDialog(driver, parent);
}
public static void waitForWindow(WebDriver driver)
throws InterruptedException {
//wait until number of window handles become 2 or until 6 seconds are completed.
int timecount = 1;
do {
driver.getWindowHandles();
Thread.sleep(200);
timecount++;
if (timecount > 30) {
break;
}
} while (driver.getWindowHandles().size() != 2);
}
public static void switchToModalDialog(WebDriver driver, String parent) {
//Switch to Modal dialog
if (driver.getWindowHandles().size() == 2) {
for (String window : driver.getWindowHandles()) {
if (!window.equals(parent)) {
driver.switchTo().window(window);
System.out.println("Modal dialog found");
break;
}
}
}
}
}
Solution in R (RSelenium):
I had a popup dialog (which is dynamically generated) and hence undetectable in the original page source code
Here are methods which worked for me:
Method 1: Simulating Pressing keys for Tabs and switching to that modal dialog
My current key is focussed on a dropdown button behind the modal dialog box
remDr$sendKeysToActiveElement(list(key = "tab"))
Sys.sleep(5)
remDr$sendKeysToActiveElement(list(key = "enter"))
Sys.sleep(15)
Method 2: Bring focus to the frame(or iframe) if you can locate it
date_filter_frame <- remDr$findElement(using = "tag name", 'iframe')
date_filter_frame$highlightElement()
Sys.sleep(5)
remDr$switchToFrame(date_filter_frame)
Sys.sleep(2)
Now you can search for elements in the frame. Remember to put adequate Sys.sleep in between commands for elements to load properly (just in case)
date_filter_element <- remDr$findElement(using = "xpath", paste0("//*[contains(text(), 'Week to Date')]"))
date_filter_element$highlightElement()
Try this code, include your object names & variable to work.
Set<String> windowids = driver.getWindowHandles();
Iterator<String> iter= windowids.iterator();
for (int i = 1; i < sh.getRows(); i++)
{
while(iter.hasNext())
{
System.out.println("Main Window ID :"+iter.next());
}
driver.findElement(By.id("lgnLogin_UserName")).clear();
driver.findElement(By.id("lgnLogin_UserName")).sendKeys(sh.getCell(0,
i).getContents());
driver.findElement(By.id("lgnLogin_Password")).clear();
driver.findElement(By.id("lgnLogin_Password")).sendKeys(sh.getCell(1,
i).getContents());
driver.findElement(By.id("lgnLogin_LoginButton")).click();
Thread.sleep(5000L);
windowids = driver.getWindowHandles();
iter= windowids.iterator();
String main_windowID=iter.next();
String tabbed_windowID=iter.next();
System.out.println("Main Window ID :"+main_windowID);
//switch over to pop-up window
Thread.sleep(1000);
driver.switchTo().window(tabbed_windowID);
System.out.println("Pop-up window Title : "+driver.getTitle());
I have tried it, it works for you.
String mainWinHander = webDriver.getWindowHandle();
// code for clicking button to open new window is ommited
//Now the window opened. So here reture the handle with size = 2
Set<String> handles = webDriver.getWindowHandles();
for(String handle : handles)
{
if(!mainWinHander.equals(handle))
{
// Here will block for ever. No exception and timeout!
WebDriver popup = webDriver.switchTo().window(handle);
// do something with popup
popup.close();
}
}
Assuming the expectation is just going to be two windows popping up (one of the parent and one for the popup) then just wait for two windows to come up, find the other window handle and switch to it.
WebElement link = // element that will showModalDialog()
// Click on the link, but don't wait for the document to finish
final JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript(
"var el=arguments[0]; setTimeout(function() { el.click(); }, 100);",
link);
// wait for there to be two windows and choose the one that is
// not the original window
final String parentWindowHandle = driver.getWindowHandle();
new WebDriverWait(driver, 60, 1000)
.until(new Function<WebDriver, Boolean>() {
#Override
public Boolean apply(final WebDriver driver) {
final String[] windowHandles =
driver.getWindowHandles().toArray(new String[0]);
if (windowHandles.length != 2) {
return false;
}
if (windowHandles[0].equals(parentWindowHandle)) {
driver.switchTo().window(windowHandles[1]);
} else {
driver.switchTo().window(windowHandles[0]);
}
return true;
}
});
Nope, Model window needs to be handle by javaScriptExecutor,Because majorly model window made up of window model,
This will works once model appeared then control take a place into model and click the expected element.
have to import javascriptexector
like below,
Javascriptexecutor js =(Javascriptexecutor).driver;
js.executescript(**<element to be clicked>**);
P.S. 1 adding my 2 cents even though the question is too old
public void PressEnterKey()
{
var simulator = new InputSimulator();
simulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
}
you can create a method like the above and call it where it is required.
P.S. 2 - you can change the keyboard inputs as well (like up arrow, down arrow, page down etc)