I am trying to automate a sharepoint-based application, which can be slow at times. In the example below, I am trying to wrap the password input into an explicit wait. Currently, Selenium runs the test to fast and it results in failure to perform the actions.
How can I wrap the password portion into a selenium explicit way?
// Enter username
var input_Username = Driver.Instance.FindElement(By.Id("username_input"));
input_Username.SendKeys("admin");
WebDriverWait wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(3000));
// Enter pasword
var input_Password = Driver.Instance.FindElement(By.Id("pw_input"));
input_Password.SendKeys("password");
Yes, you are on the right track.
WebDriverWait instance has been created, now you just need to call it like this:
WebDriverWait wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(3000));
var input_Password = wait.Until(d=> d.FindElement(By.Id("pw_input")));
input_Password.SendKeys("password");
Please refer to C# API doc for more details. Relevant classes are under OpenQA.Selenium.Support.UI Namespace, in which there is an ExpectedConditions class that would be handy.
var input_Password = wait.Until(ExpectedConditions.ElementExists(By.Id("pw_input")));
Also note that your code sets the timeout to 3000 seconds, seems way too long.
Related
I have an issue that I am facing.
I have a text in the text box that I want to delete, the problem is that
driver.find_element_by_id('foo').clear()
not work and I need something harder than this clear function that do nothing.
I used this mthood that actually worked in windows:
element.sendKeys(Keys.CONTROL + "a");
element.sendKeys(Keys.DELETE);
if I want it to run on mac and on Linux machine, how can I perform it?
please the clear() not worked please do not provide solution with the clear() method
Use execute_script:
element=driver.find_element_by_id('foo');
driver.execute_script("arguments[0].value=' ';", element);
try
driver.findElement(yourelement).sendKeys("");
or variant
use Actions action = new Actions(driver);
// ... // may be move cursor to field
action.sendKeys(Keys.ARROW_LEFT);
action.build().perform();
may be problem in selenium library error, or in the webdriver version,
or conflict with js-framework on a form?
i use this also
public void clearAndInputStringData(By locator, String text) throws Exception {
ClickElementWhenClickable(locator);
WebElement element = getWebDriver().findElement(locator);
// element.sendKeys(Keys.CONTROL + "a");
Actions actions = new Actions(getWebDriver());
actions.doubleClick(element).perform();
element.sendKeys(Keys.DELETE);
element.sendKeys(text);
}
I created an app that lets users login through my app to Wikipedia, and I achieved this goal with selenium, but I can't find a way to verify either credentials are ok or not.
I tried find by id but since failed condition doesn't display an ID it's not helping.
private void button1_Click(object sender, EventArgs e)
{
string BaseUrl = "https://en.wikipedia.org/w/index.php?title=Special:UserLogin&returnto=Main+Page";
int TimeOut = 30;
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl(BaseUrl);
var loginBox = driver.FindElement(By.Id("wpName1"));
loginBox.SendKeys("email.address#gmail.com");
var pwBox = driver.FindElement(By.Id("wpPassword1"));
pwBox.SendKeys("!SuperSecretpassw0rd");
I would like to know if entered credentials are correct or not.
A general approach to this kind of question is to ask yourself, "How can a human see this?" and then replicate this behavior in your test. In your example, how would a human detect that the login is wrong?
A human would see the error message.
Selenium on the other hand only sees the DOM tree. So for Selenium to see the error message, you need to find out where to look in the DOM tree. To do this, open your browser developer tools and find the matching section in the DOM tree:
With this in mind, a very simple solution is to find the error div that is shown when the credentials are invalid.
var error = driver.findElement(By.className("error"));
Then you can check if the element actually exists and you can use additional Selenium methods to inspect the actual contents of the error message, to see what the error is. If the field is not present then you could assume that the login succeeded. In addition you can use driver.getCurrentUrl() to inspect whether you are still located on the login page, to confirm that you are really logged in.
That being said, if you try to do any serious browser testing you should consider using the page object model (see https://www.toolsqa.com/selenium-webdriver/page-object-model/) so you don't end up with an unmaintainable mess of test cases.
As you havn't mentioned the language binding this solution is based on Java.
An elegant approach to validate whether the credentials are valid or not would be to induce a try-catch{} block to look for the element with the error inducing WebDriverWait for the desired visibilityOfElementLocated() and you can use the following Locator Strategies:
Code Block:
public class A_demo
{
public static void main(String[] args) throws Exception
{
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
options.setExperimentalOption("useAutomationExtension", false);
WebDriver driver = new ChromeDriver(options);
driver.get("https://en.wikipedia.org/w/index.php?title=Special:UserLogin&returnto=Main+Page");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input[name='wpName']"))).sendKeys("Helios.Lucifer#stackoverflow.com");
driver.findElement(By.cssSelector("input[name='wpPassword']")).sendKeys("!SuperSecretpassw0rd");
driver.findElement(By.cssSelector("button#wpLoginAttempt")).click();
try
{
new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("form[name='userlogin']>div.error>p")));
System.out.println("Unsuccessful login attempt");
}
catch (TimeoutException e)
{
System.out.println("Successful Login.");
}
driver.quit();
}
}
Console Output;
Unsuccessful login attempt
Can anyone know that how can we handle Authenticate alert box of browser in selenium Webdriver ?
I user following code but its not working.
driver.switchTo().alert().authenticateUsing(new UserAndPassword("uname", "Password"));
Here is a screenshot of what I am trying to fill in:
Does anyone know how can I enter those credentials?
You can handle this in two ways:
You can pass the username and password directly through the URL like this:
driver..get("https://MyUserName:password#staging.www.abc.com")
You can also use AutoIT Tool for handling any kind of window popups.
For this you first have to download and install AutoIt
Then download SciTE4AutoIt3
You can do scripting in it, or you can use Au3Recorder. It is not available in new versions of SciTE, but you can download it from old versions separately. Unzip it and copy:
autoit-v3.3.14.0.zip\install\Extras\Au3Record
to
[#Install Dir of AutoIt in Program files]\Extras\Au3Record
Now you can start the recorder directly by clicking Au3Record.exe or you can find it in the Script Editor window Tools >AU3Recorder.
For it you have to create a blank .au3 file in the Script Editor. Now start recording. Perform action on Window Popup. Stop when Done. Save it with .au3 format.
Now GO to Saved File location >> Right Click on the File and compile it (Compile Script(x64) or else). It will create an .exe file in the same folder.Now run that script in your Project using:
Runtime.getRuntime().exec("File Loaction/MyAutoItScript.exe");
It will work.
Try below code:
String username = "myUsername";
String password = "myPassword";
String URL = "http://" + username + ":" + password + "#" + sso.mywebsite.com/usdf/ls/dia?kkkk;
driver.get(URL); // Basically operation done here itself still if not work use further Alert code as well
Alert alert = driver.switchTo().alert();
alert.accept();
Full code will be like:
driver.get("https://sso.mywebsite.com/usdf/ls/dia?kkkk");
String url = driver.getCurrentUrl().replaceAll("https://", "");
String username = "myUsername";
String password = "myPassword";
String URL = "https://" + username + ":" + password + "#" + url;
driver.get(URL); // Basically operation done here itself still if not work use further Alert code as well
Alert alert = driver.switchTo().alert();
alert.accept();
Note : Even alert code do not required .. use it as it works for you and this code works on chrome better
Something like this?
driver.Navigate().to("http://UserName:Password#url.com")
or
WebDriverWait wait = new WebDriverWait(driver, 10);
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
alert.authenticateUsing(new UserAndPassword(*username*, *password*));
I use Java for my test automation. I have searched for a decent way to deal with these sign in pop ups and cannot find one. The most common answers are either to include in a URL as prefix prior to the real url (eg https:\username:password#www.website.com) or to use a wait for alert. These have not worked for me as: on a form submit there is no simple url to use and I am not sure as to the security including the password in the start of the url; with the wait for alert the webdriver hangs until there is a response - which only comes from submitting the login response via the pop up.
The workaround I have found is poor - I've not got it to work in a headless environment and so limits this answers usefulness. Would be great to get a real answer here. Note that I am running this in a Windows environment and if I was using Linux I have read that I could use xvfb to provide a 'screen' for sikuli and then this would work - if anyone can comment on how to do this on a Windows server that would be MUCH appreciated.
I use Sikuli for the automation of things I cannot automate via Selenium. Sikuli does many things, including letting you basically feed it images that it performs actions on.
For this purpose I run Sikuli on a thread started prior to clickin the submit that leads to the sign in pop-up. As it is running on a different thread it doesn't block the main thread, so it can still execute the log in. Once it logs in it shuts down and logging in closes the pop up and reactivates the main thread.
Specifically:
Sikuli MAVEN entry for POM:
<dependency>
<groupId>com.sikulix</groupId>
<artifactId>sikulixapi</artifactId>
<version>1.1.4-20191010.160947-268</version>
</dependency>
In the main code use a runnable executed via an executor:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
private final AtomicInteger expectedResultCount;
private final AtomicInteger publishedResultCount;
private final ExecutorService executor;
ExecutorService executor = Executors.newFixedThreadPool(5);
String processName = "asic-login";
LoginPopUp login = new LoginPopUp(this, processName);
addResultExpectation(processName);
executor.execute(login);
The runnable here implements an interface I use to keep things tidy:
The main class implements the interface to manage the threads:
public class TestRunner implements ResultPublisher{
These are functions inside the main class for thread management:
private void addResultExpectation(String process){
resultMap.put(process, new JSONObject());
expectedResultCount.addAndGet(1);
}
public void publishResult(JSONObject result){
String process = result.getString("process-name");
String strResult = result.getString("result");
resultMap.put(process, result);
publishedResultCount.addAndGet(1);
if(publishedResultCount.get() == expectedResultCount.get()){
executor.shutdown();
System.out.println("shutting down executor for run " + runId);
}
}
This is the interface
import org.json.JSONObject;
public interface ResultPublisher {
void publishResult(JSONObject result);
}
This is the runnable Runnable - an inner class in the TestRunner main class:
private class LoginPopUp implements Runnable{
private ResultPublisher publisher;
private String filePath;
private String processName;
private LoginPopUp(){
}
public LoginPopUp(ResultPublisher publisher, String processName){
this.publisher = publisher;
this.processName = processName;
}
private void publish(JSONObject result){
publisher.publishResult(result);
}
public void run(){
JSONObject result = new JSONObject();
result.put("path", filePath);
try{
Screen sd = new Screen();
ScreenUtility s = new ScreenUtility(imagesDirectory);
s.clickImage("LoginTitle.PNG", 10, 2500);
s.typeImageWithOffset("UserName.PNG", userName, 30,0);
s.typeImageWithOffset("Password.PNG",String.valueOf(password), 50,0);
s.clickImage("AsicSignIn.PNG", 10, 250);
}catch(Exception ex){
result.put("result", ex.getMessage());
result.put("process-name", processName);
publish(result);
Logger.getLogger(BCSRobot.class.getName()).log(Level.SEVERE, null, ex);
return;
}
result.put("result", "logged in successfully");
result.put("process-name", processName);
publish(result);
return;
}
}
When I use PageObject and I want to set a time to wait for elements on the page then I use ImplicitlyWait:
Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(3));
This means that when my page object is initializing:
PageFactory.InitElements(Driver, this);
Then it will wait for elements not less then 3 seconds.
Also there is another feature of Selenium that I discovered recently: RetryingElementLocator class
Code of this class: https://seleniumhq.github.io/selenium/docs/api/dotnet/html/T_OpenQA_Selenium_Support_PageObjects_RetryingElementLocator.htm
As I understand it allows to set time to wait elements on a page for PageObject.
The example of usage is the next:
IWebDriver driver = new ChromeDriver();
RetryingElementLocator retry = new RetryingElementLocator(driver, TimeSpan.FromSeconds(5));
IPageObjectMemberDecorator decor = new DefaultPageObjectMemberDecorator();
PageFactory.InitElements(retry.SearchContext, this, decor);
So the question is: if there is any difference between 2 methods and if so when it's better to use the second one?
Using Selenium, is it possible to create a virtual WebElement to use in a unit test?
#Test
public void testIt() {
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement we = (WebElement)js.executeScript("code to create and return a input element");
assertTrue("default value", we.getText());
}
I thought about using a Spy or Mock object, but WebElement doesn't have any "setter" methods and so once I create a WebElement instance, I don't know how I would give it values.
For example, would it be possible to convert a HtmlUnit web element to a Selenium WebElement (that contains attributes)?
final String html = "<html><head></head><body id='tag'><b>text</b></body></html>";
final HtmlPage page = loadPage(html);
final HtmlUnitWebElement node = page.getHtmlElementById("tag");
WebElement we = node.findElement(By.xpath(".//b"));
You can write a proxy class with own implementation. I dont know about Java Selenium, but .Net Selenium has proxy WebDriver that used by PageObjectFactory and this proxy WebDriver returns proxy WebElement class that works in lazy way - it does initialization on the first access to that object.
This may help you as example - https://github.com/SeleniumHQ/selenium/tree/master/java/client/src/org/openqa/selenium/support/events . You can check EventFiringWebDriver that works like a proxy too and creates proxy EventFiringWebElement object.
So you can write own implementation for WebElement that will have setters and you can use them with test data.