Magnesia
Magnesia

Reputation: 21

Selenium can't find 99% of elements, why?

I'm using Selenium with Python and Firefox on Windows 7. Running through my script, at some point Selenium can't find any elements beside and after I navigated to a certain part of a website. The website belongs to an E-Mail provider called freemail (https://web.de/). I have set up a test account to complete a training project from chapter 11 of the book "Automate the Boring Stuff with Python".

Python, Selenium and Firefox are all up to date. And before this certain part of the website everything was working fine (including finding tags, class names, id's etc.). I tried like 10 different ways to click one of the ways to navigate to the inbox of the E-Mail provider but had no luck in making it work.

Here is the HTMLcode with the highlighted element I want Selenium to click. Here another image of the Website itself with the button highlighted in the upper left corner.

And this is the code for my script:

## This program navigates through the website of an
## e-mail provider and sends a mail automatically.

# Import necessary modules
from selenium import webdriver
# Mail account info
mailLink = 'https://web.de/'
mailAddress = '[email protected]'    # This is just a test account
mailPw = 'ewaa11ewaa11'

# Recipient % content of the e-mail
recipient = '[email protected]'
mailContent = 'Test this awesome string.'

# Set up browser
browser = webdriver.Firefox()
browser.get(mailLink)

# Log into account
browser.find_element_by_class_name('icon-freemail').click()
browser.find_element_by_id('freemailLoginUsername').send_keys(mailAddress)
pwElem = browser.find_element_by_id('freemailLoginPassword')
pwElem.send_keys(mailPw)
pwElem.submit()

# Close notification overlay if it pops up
try:
    browser.find_element_by_class_name('layerCloser').click()
except:
    pass


## At this point Selenium can't Find 99% of elements including the one I need

## Testing if Selenium finds basic elements
testElem1 = browser.find_element_by_tag_name('html')   # works
testElem2 = browser.find_element_by_tag_name('body')   # works
testElem3 = browser.find_element_by_tag_name('div')   # works

## Click link to inbox (all of these variants won't work somehow)
linkToInbox = browser.find_element_by_class_name('nx-track-sec-click-communication-newmail')   # try by class_name
linkToInbox = browser.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/ul/li[3]/a")   # try by XPath
linkToInbox = browser.find_element_by_link_text('E-Mail schreiben')   # try by link_text
linkToInbox = browser.find_element_by_css_selector('a.nx-track-sec-click-communication-newmail')   # try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a.newmail')   # try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a.nx-track nx-track-sec-click-communication-newmail newmail')   # another try by CSS selector
linkToInbox = browser.find_element_by_css_selector('a[title="E-Mail schreiben"]')   # another try by CSS selector

## TODO: Click link to write a new mail
## TODO: Fill in recipient and mail content
## TODO: Send mail and close program

I guess it has something to do with an iframe? But I'm a beginner and I don't know how to handle this :/

Thanks in advance!


EDIT: I solved the problem by finding another button that linked to the inbox with browser.find_element_by_xpath("/html/body/atlas-app/atl-navbar/atl-actions-menu/div[1]/div[1]/atl-menu-item[2]/pos-icon-item/span/span").click(). This button is not within an iframe, so no problem here.

However, it is still strange that I can't enter any iframes. Here is another image to make it more clear. Does anybody know how to switch to that iframe? browser.switch_to.default_content() and then browser.switch_to.frame('home') doesn't do the trick...


SECOND EDIT: KunduK's answer did it. The problem was, that the script needs to wait for the iframe to become available and then for the button to become available after that. See his post further down for the exact approach. Thanks everyone!

Upvotes: 2

Views: 261

Answers (3)

KunduK
KunduK

Reputation: 33384

To click on the E-Mail schreiben link you need to switched to iframe first and then click on link.Use WebDriverWait and frame_to_be_available_and_switch_to_it and then use element_to_be_clickable

WebDriverWait(browser,20).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,'home')))
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//div[@id="navigation"]//ul//li[@class="item"]//a[@title="E-Mail schreiben"]'))).click()

You need to use following imports to execute above code.

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

Upvotes: 1

Corey Goldberg
Corey Goldberg

Reputation: 60614

I guess it has something to do with an iframe?

Since the elements you are trying to find are in an iframe, you must first switch to the iframe before finding the elements. Your iframe has a name=home attribute, so you should be able to add:

driver.switch_to.frame('home')

... then find the elements.

Once you are done interacting with the iframe and want to switch back to the top level content, use:

driver.switch_to.default_content()

Upvotes: 1

X3R0
X3R0

Reputation: 6344

Option 1

linkToInbox = browser.find_element_by_css_selector('a.nx-track.nx-track-sec-click-communication-newmail.newmail')   # try by CSS selector

Option 2

use the title property of the anchor link

linkToInbox = browser.find_element_by_css_selector('a[title="E-Mail schreiben"]')

option 3

re-read the docs: https://selenium-python.readthedocs.io/locating-elements.html

Upvotes: 0

Related Questions