Reputation: 1742
As an exercise in learning Selenium WebDriver I am trying to visit the Twitter log in page and log in. I am finally able to navigate to the page and get the desired* element for the username field:
<input class="text-input email-input js-signin-email" name="session[username_or_email]" type="text">
*I have tried to find what types of elements sendKeys
operates with but I can't. I think this element is the one I want since the tag is of the <input>
type.
When I call sendKeys
on the element after assigning it I get an ElementNotInteractableException
. I have tried using explicit waits with the ExpectedConditions
of visibilityOf
and invisibilityOf
. The respective interpretation of the TimeoutException
and ElementNotInteractableException
tells me that the element I mentioned above loads in the DOM tree but never becomes visible*. How do I get around this? Is there a solution using a JavascriptExecutor
?
*The surrounding html might reveal why the element remains invisible:
<form class="t1-form clearfix signin js-signin"
action="https://twitter.com/sessions" method="post">
::before
<fieldset>
<legend class="visuallyhidden">Log in</legend>
<div class="clearfix field">
::before
<input class="text-input email-input js-signin-email"
name="session[username_or_email]" type="text">
.
**For those on the hunt, this question is helpful to look at especially if the issue is caused by the click
method instead.
Upvotes: 2
Views: 5142
Reputation: 1742
EDIT: apparently I didn't do quite enough research, although I didn't see this question on StackOverflow. Going to leave this question in case it helps someone.
Using JavascriptExecutor
(Source 1.):
import org.openqa.selenium.JavascriptExecutor;
JavascriptExecutor executor= (JavascriptExecutor) driver;
executor.executeScript(script, arguments);
sendKeys
alternative we need to execute a bit of JS that sets the text value of the element using dot notation. We have to find the element first. (Source 1.) Use document.getElementById('id')
, document.getElementsByTagName('name')
, or document.getElementsByClassName('class')
to find the element (Source 2.). Note that for the last two options for locating the element multiple elements are gathered, so index the one you want.An example line of code that turned out to be my solution:
executor.executeScript("document.getElementsByClassName('js-username-field email-input js-initial-focus')[0].value='someValue';");
Note that .getElementById('id')
is probably preferred, but in my case the website designers decided to be uncooperative and not provide an id attribute.
Here are two (incredible!) resources on the subject--check them out!
Upvotes: 1
Reputation: 5637
You can use this code:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test {
public static void main(String[] args) throws InterruptedException {
final WebDriver driver = new ChromeDriver();
driver.get("https://twitter.com/login?lang=en");
WebDriverWait wait = new WebDriverWait(driver, 10);
// locate login input
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@placeholder = 'Phone, email or username']")));
WebElement loginInput = driver.findElement(By.xpath("//input[@placeholder = 'Phone, email or username']"));
loginInput.click();
loginInput.sendKeys("login");
// locate password input
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//fieldset//input[@placeholder = 'Password']")));
WebElement passInput = driver.findElement(By.xpath("//fieldset//input[@placeholder = 'Password']")); // this xPath does the trick
passInput.click();
passInput.sendKeys("password");
Thread.sleep(3000); // only to see the result
//locate submit button
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//button[@type= 'submit']")));
WebElement submitBtn = driver.findElement(By.xpath("//button[@type= 'submit']"));
submitBtn.click();
Thread.sleep(3000); // only to see the result
driver.quit();
}
}
Upvotes: 1