selenium webdriver with variable - selenium

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.

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 not inputting the whole text into a text box

I am using Selenium to clear out the existing Shipping Address fields of a Salesforce Account object and to assign new values. I am coding in C# and running on Visual Studio 2019.
I am getting cases where the textboxes are not getting fully populated.
My code is below.
private string shippingStreet = "56789 Liberty Street"; // 80 character limit
private string shippingCity = "Toronto"; // 40 character limit
private string shippingState = "ON"; // 80 character limit
private string shippingZip = "87654"; // 20 character limit
private string shippingCountry = "Canada"; // 80 character limit
IWebElement shStreet = driver.FindElement(By.XPath("//textarea[#placeholder='Shipping Street']"));
shStreet.Clear();
shStreet.SendKeys(shippingStreet);
IWebElement shCity = driver.FindElement(By.XPath("//input[#placeholder='Shipping City']"));
shCity.Clear();
shCity.SendKeys(shippingCity);
IWebElement shState = driver.FindElement(By.XPath("//input[#placeholder='Shipping State/Province']"));
shState.Clear();
shState.SendKeys(shippingState);
IWebElement shZip = driver.FindElement(By.XPath("//input[#placeholder='Shipping Zip/Postal Code']"));
shZip.Clear();
shZip.SendKeys(shippingZip);
IWebElement shCountry = driver.FindElement(By.XPath("//input[#placeholder='Shipping Country']"));
shCountry.Clear();
shCountry.SendKeys(shippingCountry);
Please see the screenshot.
I fix this issue by adding an extra space after city, state, zip code, and country but I was wondering if there is a better solution.
You can try this method:
Just call it and add the xpath: WaitForElementDisplayed_byXPathTime("//myPath");
WaitForElementDisplayed_byXPathTime
public static void WaitForElementDisplayed_byXPathTime(string value)
{
var wait = new WebDriverWait(Driver, new TimeSpan(0, 0, 30));
wait.Until(webDriver => webDriver.FindElement(By.XPath(value)).Displayed);
}
The other thing I have done on these is create a new type method for individual characters like you would on mobile. This just slows it down a bit.
public static void TypeCharsIndividually(IWebElement element, string expectedValue)
{
//use your code for element displayed and element enabled
element.Click();
element.Clear();
foreach (char c in expectedValue)
{
element.SendKeys(c.ToString());
Thread.Sleep(100);
}
}
java click
public static void ClickJava(IWebElement element)
{
IJavaScriptExecutor executor = driver IJavaScriptExecutor;
executor.ExecuteScript("arguments[0].click();", element);
}
WaitForElement
public static bool WaitForElementDisplayed_byXPath(string path)
{
var result = true;
try { _wait.Until(webDriver => driver.FindElement(By.XPath(path)).Displayed); }
catch (StaleElementReferenceException) { WaitForElementDisplayed_byXPath(path); }
catch (NoSuchElementException) { WaitForElementDisplayed_byXPath(path); }
catch (WebDriverTimeoutException) { result = false; }
return result;
}
This is a Salesforce issue. I see the problem even when i am manually updating a shipping address field and I tab to another field.

How to pass multiple locators in Selenium webdriver to fetch an element on a page

Hi can anyone pls solve this. When i write a code to automate sometimes the elements are not identified and sometimes its not found even they are present, means even if the id is present it says element not found error. So I a trying to create a method where i would pass all the dom objects i find like Ex :
public static void Click(WebDriver driver, String name,Sting linktext,Sting id,Sting Xpath,String css)
{
driver.findElement(new ByAll(By.name(name),
By.linkText(linktext),
By.id(id),
By.xpath(xpath),
By.cssSelector(css))).click();
}
And i would pass what ever value i find in source page like sometimes it will have oly id or it ll have oly link text Ex:(when i import this method in other class)
Click(Webdriver driver, "username",null,"","//[fas].user");
is this the correct way to pass the arguments. can i pass like null and "" (blank). Pls help this would become a one simple effective framework for me.
you can use this 2 methods
public static WebElement findElement(WebDriver driver, By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(selector));
return findElement(driver, selector);
}
public static WebElement findElementSafe(WebDriver driver, By selector, long timeOutInSeconds) {
try {
return findElement(driver, selector, timeOutInSeconds);
} catch (TimeoutException e) {
return null;
}
}
public static void waitForElementToAppear(WebDriver driver, By selector, long timeOutInSeconds, String timeOutMessage) {
try {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
} catch (TimeoutException e) {
throw new IllegalStateException(timeOutMessage);
}
}
----------------
public static void click(WebDriver driver , By ... selector ){
for (By byPath : selector) {
WebElement element = findElementSafe(driver, byPath, 1);
if(element != null){
element.click();
}
}
}

checking for element present or not using Selenium WebDriver page factory?

Checking for elements with findElements using normal WebDriver method is easy like:
boolean exists = driver.findElements( By.id("...") ).size() != 0
Elements initialized by Page Factory are like:
#FindBy(name = "filter")
private WebElement filterText;
But how can we check in our page that this element is present on the page or not ??
The isDisplayed() method should do the job:
if (filterText.isDisplayed()) {
filterText.doStuff();
}
here's something i came up with:
public boolean isElementPresent(WebElement we)
{
try {
we.getTagName();
} catch (NoSuchElementException e) {
flag = 1;
}
if (flag == 1)
return true;
else
return false;
}
which is pretty basic but effective way to do it..

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)