Reputation: 879
I'm trying to automate a checkout process on this website . I am at the 4th stage where you click the "Credit Card" option in "Payment Information" and I am trying to send_keys
to input in my credit card numbers.
However, I notice that after clicking the CC option, the page loads for a bit so I used an explicit wait for that element but that is not working. Any help would be appreciated.
ccNumber = session.find_element_by_css_selector('input[name=credit-card-number]')
wait = WebDriverWait(session, 100)
wait.until(EC.element_to_be_selected(ccNumber))
This is the error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"input[name=credit-card-number]"}
Upvotes: 1
Views: 1550
Reputation: 193108
The <input>
field for the Credit Card number is within an <iframe>
so you have to:
Code Block:
WebDriverWait(session, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"braintree-hosted-field-number")))
WebDriverWait(session, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.number#credit-card-number"))).send_keys("0000000000000000")
Upvotes: 2
Reputation: 245
You could wait until the Loading spinner no longer appears on the page anymore before checking for the credit card input. We have a C# solution that you could try to adapt to python where you wait in a loop for an element to be displayed, catching the exceptions until reaching the timeout.
//Assert an element is displayed before the timeout milliseconds run out.
public void AssertElementIsDisplayed(int timeout, IWebElement element, string elementName = "element")
{
Action<IWebElement> target = delegate (IWebElement e) {
if (e == null)
{
throw new AssertionException("Failed to find " + elementName + ". It is null");
}
if (!e.Displayed)
{
elementName = (elementName == "element" && !String.IsNullOrEmpty(e.GetAttribute("title"))) ? e.GetAttribute("title") : elementName;
throw new AssertionException("Expected (" + elementName + ") to be displayed but it was not");
}
};
AssertInLoop(element, (long)timeout, 100L, target);
}
//Assert some Action on a WebElement for as long as the timeoutMillis allow.
private void AssertInLoop(IWebElement element, long timeoutMillis, long millisBetweenAttempts, Action<IWebElement> callable)
{
AssertionException lastAssertionError = null;
WebDriverException lastWebDriverException = null;
long startTime = DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond;
if (timeoutMillis < 500 || timeoutMillis > 120 * 1000)
{
throw new ArgumentException("Timeout outside expected range. timeout_millis=" + timeoutMillis);
}
long millisLeft = timeoutMillis;
while (millisLeft >= 1)
{
long lastAttemptStartMillis = DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond;
try
{
callable(element);
return;
}
catch (AssertionException e)
{
lastAssertionError = e;
lastWebDriverException = null;
}
catch (StaleElementReferenceException e)
{
lastAssertionError = null;
lastWebDriverException = e;
}
catch (NotFoundException e)
{
lastAssertionError = null;
lastWebDriverException = e;
}
catch (SystemException e)
{
throw e;
}
long elapsedMillis = (DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond) - startTime;
millisLeft = timeoutMillis - elapsedMillis;
if (millisLeft >= 1)
{
long millisElapsedDuringThisAttempt = (DateTimeOffset.Now.Ticks / TimeSpan.TicksPerMillisecond) - lastAttemptStartMillis;
long millisToSleep = millisBetweenAttempts - millisElapsedDuringThisAttempt;
if (millisToSleep > 0)
{
Thread.Sleep((int)millisToSleep);
}
}
}
if (lastAssertionError != null)
{
throw lastAssertionError;
}
else if (lastWebDriverException != null)
{
throw lastWebDriverException;
}
}
Upvotes: 0