1

I am just starting to learn Selenium and wanted to implement authentication on the "https://mail.ru/" page. There are two "Login" buttons that, when clicked, open a window with an authentication form. However, Selenium does not see the elements of the page that appeared after clicking the "Login" buttons. I have tried searching by xPath, class_name, etc. How can I solve this problem?

from selenium.webdriver.common.by import By
import time


class TestLogMail:

    def test_log(self, browser_web):

        browser_web.get('https://mail.ru/')
        time.sleep(3)

        button_log = browser_web.find_element(By.XPATH, '//*[@id="mailbox"]/div[1]/button').click()
        time.sleep(5)

        input_log = browser_web.find_element(By.CSS_SELECTOR, 'input[name="username"]')
        input_log.send_keys('mail')
        time.sleep(5)

        button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div[2]/div[3]/div/div/div[1]/button').click()
        time.sleep(5)

        input_pass = browser_web.find_element(By.XPATH, '/html/body/div[1]/div[2]/div/div/div/div[2]/div/div/form/div[2]/div/div[2]/div/div/div/div/div/input')
        input_pass.clear()
        input_pass.send_keys('pass')
        time.sleep(5)

        button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div/div[3]/div/div/div[1]/div/button').click()
        time.sleep(5)

        browser_web.save_screenshot('result_log.png')
import pytest
from selenium import webdriver


@pytest.fixture
def browser_web():
    options = webdriver.ChromeOptions()
    driver = webdriver.Chrome(options=options)
    yield driver
    driver.quit()

Error

deadshot
  • 8,881
  • 4
  • 20
  • 39
Daniil
  • 13
  • 3

3 Answers3

1

The element Account name is within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.

  • Induce WebDriverWait for the desired element to be clickable.

  • You can use either of the following locator strategies:

    • Using CSS_SELECTOR:

      browser_web.get("https://mail.ru/")
      WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='enter-mail-primary']"))).click()
      WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src^='https://account.mail.ru/login/?mode=simple']")))
      WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='username']"))).send_keys('Daniil')
      
    • Using XPATH:

      browser_web.get("https://mail.ru/")
      WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[@data-testid='enter-mail-primary']"))).click()
      WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(@src, 'https://account.mail.ru/login/?mode=simple')]")))
      WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='username']"))).send_keys('Daniil')
      
  • Note : You have to add the following imports :

     from selenium.webdriver.support.ui import WebDriverWait
     from selenium.webdriver.common.by import By
     from selenium.webdriver.support import expected_conditions as EC
    
  • Browser Snapshot:

Danil


Reference

You can find a couple of relevant discussions in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
1

That's due to the iframe located on that web page:

You must switch to the iframe first before interacting with elements inside. https://www.selenium.dev/documentation/webdriver/interactions/frames/

iframe = driver.find_element(By.CSS_SELECTOR, "iframe.ag-popup__frame__layout__iframe")
driver.switch_to.frame(iframe)

Now you can interact with elements inside the iframe.

Michael Mintz
  • 9,007
  • 6
  • 31
  • 48
0

As I can see in while clicking on login it is opening another popup and the elements are within an iframe.

<iframe src="https://account.mail.ru/login/?mode=simple&amp;v=2.10.0&amp;account_host=account.mail.ru&amp;type=login&amp;allow_external=1&amp;app_id_mytracker=58519&amp;success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&amp;project=home&amp;from=navi&amp;parent_url=https%3A%2F%2Fmail.ru%2F&amp;responsive=compact" class="ag-popup__frame__layout__iframe" scrolling="no" frameborder="0"></iframe>

Here is you can follow to handle this situation:

iframe = driver.find_element_by_xpath('//iframe[@src="https://account.mail.ru/login/?mode=simple&amp;v=2.10.0&amp;account_host=account.mail.ru&amp;type=login&amp;allow_external=1&amp;app_id_mytracker=58519&amp;success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&amp;project=home&amp;from=navi&amp;parent_url=https%3A%2F%2Fmail.ru%2F&amp;responsive=compact"]')
driver.switch_to.frame(iframe)

And then you can proceed with your rest of the test steps.

I know this xpath is little weired. But you can ask your developer to put an ID to this iframe element which will definitely help to use switch to frame id method directly.