1

driver.find_element_by_id('username').send_keys('thisIsAString') Selenium is able to type in the password fields but not the username field. I'm using the same code for both of them but for some reason the username is acting weird.

<input placeholder="Choose username" required="" name="username" messages="[object Object]" iframename="top" pattern=".{1,40}" id="username" class="input">

That is the username field's HTML
Any help will be greatly appreciated!

Edit:
Code:

from selenium import webdriver
import time

url = 'https://protonmail.com/signup'

driver = webdriver.Chrome('chromedriver')
driver.get(url)



time.sleep(2)

driver.find_element_by_class_name('panel-heading').click()

time.sleep(4)

driver.find_element_by_id('freePlan').click()

time.sleep(20)

driver.find_element_by_id('username').send_keys('thisIsAString')

time.sleep(1.5)

driver.find_element_by_id('password').send_keys('passwordForUser')

time.sleep(2)

driver.find_element_by_id('passwordc').send_keys('passwordForUser')

time.sleep(2)

driver.find_element_by_class_name('signUpProcess-btn-create').click()

time.sleep(1)

driver.find_element_by_id('confirmModalBtn').click()

Error Message:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"username"} (at line 21)

roh
  • 43
  • 6
  • It's hard to tell. Maybe you can provide some piece of code. Are there any error messages displayed? Maybe it's a simple thing at the end like a missing semicolon. – JKD Sep 09 '20 at 08:06
  • When loading the page, the username input field is not loaded as fast as the password field. I strongly assume that the problem is that the input field is not loaded yet, but the code is already accessing it. Make sure your page completely loads before you access it's content. – JKD Sep 09 '20 at 08:15

2 Answers2

2

I can see there are couple of iFrames in your page. Also since its an Ajax page lot of components are loading separately so best bet here is explicitwait.Note, time.sleep() is not a very realiable method of wait and it will make your test unpredictable. Use below code:

driver.get("https://protonmail.com/signup")
#Wait for upto 30 sec for Free plan div to appear
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, "//div[@aria-controls='plan-free']"))).click()

#Wait for upto 30 sec for Select Free plan button to appear
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, "freePlan"))).click()
#Wait and switch to iframe containing user id field
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title ='Registration form' and @class='top']")))
WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.ID, "username")))
driver.find_element_by_id('username').send_keys("abc")
driver.switch_to.default_content() # Switch to default window
driver.find_element_by_id('password').send_keys("abc")
driver.find_element_by_id('passwordc').send_keys("abc")

Note, if you wish to enter recovery email and click on Create Account button there is one more iframe which you need to switch. Use below:

#To enter recovery Email and click on create account button
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title ='Registration form' and @class='bottom']")))
driver.find_element_by_id('notificationEmail').send_keys("xyz")
driver.find_element_by_name('submitBtn').click()
driver.switch_to.default_content()

enter image description here

rahul rai
  • 2,260
  • 1
  • 7
  • 17
0

Your input field is not loeaded yet, but the code is accessing it. You can use the following code to wait until your input field is loaded. And then you can access it.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "username"))
    )
finally:
    driver.quit()

Generally always make sure your page is fully loaded before accessing any elements on it.


UPDATE: I just saw that you are using an iFrame here. Try adding an ID to the iFrame tag and then wait for it to load like this:

HTML:

<iframe id="iFrameTagID" title="Registration form" scrolling="no" class="top" data-name="top" sandbox="allow-scripts allow-same-origin allow-popups allow-top-navigation" src="https://secure.protonmail.com/abuse.iframe.html?name=top"></iframe>

Selenium:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "iFrameTagID"))
    )
finally:
    driver.quit()
JKD
  • 1,279
  • 1
  • 6
  • 26
  • now its stuck on loading – roh Sep 09 '20 at 08:31
  • now it is giving me this error: ``raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:`` – roh Sep 09 '20 at 08:37
  • I just saw that you are using an iFrame here. Of course it won't work in that case. Can you add an ID to the iFrame tag? Look at my edited answer. – JKD Sep 09 '20 at 08:40
  • oh ok ill try it out! – roh Sep 09 '20 at 08:42
  • ```File "C:\Users\Ro-Fi\Desktop\Emails\emails.py", line 26, in element = WebDriverWait(driver, 10).until( File "C:\Users\Ro-Fi\AppData\Roaming\Python\Python38\site-packages\selenium\webdriver\support\wait.py", line 80, in until raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:``` Giving me this error – roh Sep 09 '20 at 08:45
  • Did you successfully assign an ID to the iFrame tag? I can't see the ID when opening your page. – JKD Sep 09 '20 at 08:47
  • @DeniJuric we can not assigne an ID as both the iFrames dont have any id or name. You can use xpath however. – rahul rai Sep 09 '20 at 09:36
  • @rahulrai that's bad. But the main problem is that the accessed element isn't loaded yet and therefore can't be accessed and modified. As you pointed out, he could use XPath instead. – JKD Sep 09 '20 at 10:39