I am trying to use Selenium to sign up an email account automatically whenever I need to. It's just a fun learning project for me. For the life of me I don't understand why it can't find the element. This code works fine on the sign-in page but not the sign-up page. I have tried all different Selenium commands and even tried using the ID and class name. Either is says it can't locate the element or that it is not reachable by keyboard.
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
options = Options()
driver = webdriver.Firefox(options=options, executable_path=r'geckodriver.exe')
driver.get("https://mail.protonmail.com/create/new?language=en")
time.sleep(10)
username_input = driver.find_element_by_id("username").send_keys("testusername")
Also here is the HTML code: https://i.imgur.com/ZaBMTzG.png
The username field is in iframe, you need to switch to iframe to make this work.
Below is the code that works fine :
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
read more about iframe here
learn more about how to switch to iframe/frame/framset using Python
selenium Bindings here
Update :
wait = WebDriverWait(driver, 30)
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
driver.switch_to.default_content()
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(5)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='bottom']"))
wait.until(EC.element_to_be_clickable((By.NAME, "submitBtn"))).click()
I'm not sure if I've seen enough code to diagnose, but I think the way you are defining username_input seems problematic. driver.find_element_by_id("username").send_keys("testusername") doesn't actually return anything so it seems like you are setting username_input = null.
Related
I am trying to learn Selenium in Python and I have faced a problem which stopped me from processing.
As you might know, previous versions of Selenium have different syntax comparing the latest one, and I have tried everything to fill the form with my code but nothing happens. I am trying to find XPATH element from [https://demo.seleniumeasy.com/basic-first-form-demo.html] but whatever I do, I cannot type my message into the message field.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
import time
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
service = ChromeService(executable_path="C:/Users/SnappFood/.cache/selenium/chromedriver/win32/110.0.5481.77/chromedriver.exe")
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(1000)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
By this code, I expect to fill the message field in the form and click the "SHOW MESSAGE" button to print my typed text, but what happens is that my code only opens a new Chrome webpage with empty field.
I have to mention that I don't get any errors by PyCharm and the code runs with no errors.
I would really appreciate if you help me through this to understand what I am doing wrong.
You need to wait for the page loads correctly.
For this, the best approach is using WebDriverWait:
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
# Wait for the page to load
wait = WebDriverWait(driver, 10)
wait.until(lambda driver: driver.find_element(By.XPATH, '//*[#id="user-message"]'))
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
Tested, it works fine.
Also you can use time.sleep() to wait the load if you know the loading times:
import time
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(5)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
time.sleep(5)
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
time.sleep(5)
with this xpath you have two elements //*[#id="user-message"] . you need to make it unique. Try below xpath this will work as expected.
message_field = driver.find_element(By.XPATH,'//input[#id="user-message"]')
browser snapshot:
Ok, attempt to use Selenium on a website : lefigaro.fr, but no class related to the RGPD popup to be found by Selenium, even after a switch to frame. :/
I'm juste looking a reliable way to close it.
It goes this way :
from selenium import webdriver
WINDOW_SIZE = "1920,1080"
ADRESSE = 'https://www.lefigaro.fr/'
driver = webdriver.Firefox() #the chrome version was even worse, geckodriver a the root
driver.get(ADRESSE)
elt = driver.find_element_by_class_name("sc-18sn7k8-1") #error
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
elt = driver.find_element_by_class_name("sc-18sn7k8-1") #error
You can switch to iframe via index.
It seems that popup is the only iframe on the page, so perhaps this will work:
driver.switch_to.frame(0) # or perhaps (1)
EDIT:
It seems the page already is in an iframe when it loads.
Do driver.switch_to.default_content() first.
Then it seems the iframe you want is (3):
driver.switch_to.frame(3)
Hope this works.
Hmm, actually, not quite... I'll spend some more time on this.
Im trying to automate blog posting using selenium and python
Able to locate element using Inspect element in browser
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get('https://www.blogger.com/go/signin')
email = browser.find_element_by_id('identifierId')
email.send_keys("xxxxxx#gmail.com")
email.send_keys(Keys.RETURN)
time.sleep(5)
password = browser.find_element_by_name("password")
password.send_keys("xxxxxx")
password.send_keys(Keys.RETURN)
time.sleep(5)
newpost = browser.find_element_by_partial_link_text("editor")
posttitle = browser.find_element_by_name("K3JSBVB-C-b titleField textField K3JSBVB-C-a")
error
Unable to locate element: [name="K3JSBVB-C-b titleField textField K3JSBVB-C-a"]
This K3JSBVB-C-b class attribute looks dynamic, I would rather suggest sticking to the New post text instead.
The relevant XPath expression would be something like:
//a[text()='New post']
Also consider using Explicit Wait as using sleep is an antipattern you should be avoiding
new_post = WebDriverWait(browser, 10).until(
expected_conditions.element_to_be_clickable(By.XPATH("//a[text()='New post']")))
new_post.click()
More information: How to use Selenium to test web applications using AJAX technology
I have done a little research and could not find any answer specific to Selenium WebDriver with Python.
I can successfully sign into the page but I cannot find way(s) to verify that the login was successful. Page title does not work for me since it does not change.
Python Selenium documentation does not have any good explanation or examples.
All I want to do after this code is to put a line and assert that the username "Tuto" is visible on the page
LoginButtonLocator = "//a[contains(text(), 'Login')]"
facebookConnectButtonLocator = "//a[contains(text(), 'Connect with Facebook')]"
facebookLoginLocatorID = "email"
facebookPasswordLocatorID = "pass"
facebookLoginButtonLocatorID = "loginbutton"
LoginButtonElement = WebDriverWait(driver, 20).until(lambda driver: driver.find_element_by_xpath(LoginButtonLocator))
LoginButtonElement.click()
facebookConnectButtonElement = WebDriverWait(driver, 20).until(lambda driver: driver.find_element_by_xpath(facebookConnectButtonLocator))
facebookConnectButtonElement.click()
facebookLoginElement = WebDriverWait(driver, 20).until(lambda driver: driver.find_element_by_id(facebookLoginLocatorID))
facebookLoginElement.send_keys(facebookID)
facebookPasswordElement = WebDriverWait(driver, 20).until(lambda driver: driver.find_element_by_id(facebookPasswordLocatorID))
facebookPasswordElement.send_keys(facebookPW)
facebookLoginButtonElement = WebDriverWait(driver, 20).until(lambda driver: driver.find_element_by_id(facebookLoginButtonLocatorID))
facebookLoginButtonElement.click()
I am working with the Javascript API instead of the Python version, so the syntax is different, but here is how I would get about it (using mocha as a test framework):
facebookLoginButtonElement.click().then(function(_) {
driver.findElement(By.xpath('//a[text() = "Tuto"]')).then(function(userLink) {
assert.ok(userLink);
});
});
In the javascript version, if <a ...>Tuto</a> can't be found there would be an error before the callback is called, so the assertion would be redundant (would only get there if the link was found), but I find it as self-documenting so I add the assert.
Just try to find an element using xPath:
wait = WebDriverWait(browser, 10)
find_username = wait.until(EC.presence_of_element_located((By.XPATH,'//span[contains(text(), "Alex")]')))
assert find_username
Hope, it will help you.
I'm writing it considering that you are using webdriver_manager for Chrome, though it doesn't create many effects, You can use the code in both scenarios with webdriver_manager or without as well provided that you have made significant changes in adding executable path for webdriver if not using webdriver_manager. Here you go...
from selenium import webdriver
// this was for importing webdriver
from webdriver_manager.chrome import ChromeDrivermanager
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://somedummy.domain.com/login")
driver.find_element_by_name("username").send_keys("somedummyvalidated#email.com")
driver.find_element_by_name("password").send_keys("someDummyPass")
driver.find_element_by_id("btnLogin").click()
this block was about sending keys, now if you are logged in correctly then the page title must change. Just use the below code to fetch the title and use assert or match the titles before and after login.
driver.title
As a regular task within my job role i often have to download full Facebook accounts from within a users account. I am trying to improve my workflow and automate this if i can.
I have tried searching for this topic on the site and although many cover the login part i am yet to locate a question that deals with the popup windows of Facebook. If i am wrong i apologise and please amend the post accordingly.
As a starting point i have decided to start learning python and am using this to script the process with a little help from selenium and Chrome Driver. I have managed to write the code to login and navigate to the correct page and click the initial link 'download a copy'. I am struggling however to get the script to locate and click the 'Start My Archive' button within the popup window.
Here is the code that i have used so far including the several alternative code blocks that i have tried commented out at the bottom:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
#Global Variables
target = "john.doe.7"
username = "john#doe.com"
password = "Password"
sleep = 5
#Finds and locates the ChromeDriver
driver = webdriver.Chrome("C:\Python35-32\ChromeDriver\chromedriver.exe")
#Set Chrome Options
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications": 2}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
#Directs browser to webpage
driver.get('http://www.facebook.com');
#code block to log in user
def logmein():
search_box = driver.find_element_by_name('email')
search_box.send_keys(username)
search_box = driver.find_element_by_name('pass')
search_box.send_keys(password)
search_box.submit()
#code to go to specific URL
def GoToURL(URL):
time.sleep(sleep) # Let the user actually see something!
driver.get(URL);
logmein()
GoToURL('https://www.facebook.com/'+'settings')
link = driver.find_element_by_link_text('Download a copy')
link.click()
#driver.find_element_by.xpath("//button[contains(., 'Start My Archive')]").click()
#driver.find_element_by_css_selector('button._42ft._42fu.selected._42gz._42gy').click()
#driver.find_element_by_xpath("//*[contains(text(), 'Start My Archive')]").click()
#driver.find_element_by_css_selector('button._42ft._42fu.layerConfirm.uiOverlayButton.selected._42g-._42gy').click()
#from selenium.webdriver.common.action_chains.ActionChains import driver
#buttons = driver.find_elements_by_xpath("//title[contains(text(),'Start My Archive')]")
#actions = ActionChains(self.driver)
#time.sleep(2)
#actions.click(button)
#actions.perform()
Just add this to your code and run if it is working or not. Always use CssSelector.
Look i ran the below code in eclipse with java and I'm not aware of python so if something is wrong in syntax , i apologies. Just Try this and see.
driver.implicitly_wait(10)
Startmyarchive = driver.find_element_by_css_selector("._42ft._42fu.selected._42gz._42gy")
Startmyarchive.click()
driver.implicitly_wait(10)
Acknowledge = driver.find_element_by_css_selector("._42ft._42fu.layerConfirm.uiOverlayButton.selected._42g-._42gy")
Acknowledge.click()
driver.implicitly_wait(10)
ClickOkay = driver.find_element_by_css_selector("._42ft._42fu.layerCancel.uiOverlayButton.selected._42g-._42gy")
ClickOkay.click()
Happy Learning :-) Do reply back for any query.