python-3.xdebuggingselenium-webdriverselenium-chromedriverwindow-handles

Why does this new window notification appear only when the user has manually pressed a button in a chromedriver instance? Selenium related


I have a simple python program that opens this page with chromedriver.exe, then it clicks on the wallet icon located at the top right corner of that page, for then clicking on the MetaMask wallet button, here:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

opt.add_argument('--user-data-dir='+r'C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data') #Add the user data path as an argument in selenium Options
opt.add_argument("--profile-directory=Default") #Add the profile directory as an argument in selenium Options
s = Service(r'C:\Users\ResetStoreX\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe') #Use the chrome driver located at the corresponding path  

driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions
driver.implicitly_wait(10)
driver.get('https://opensea.io/') #go to the opensea main page.

initial_page = driver.current_window_handle  #make the previous page the current one
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button'))) #wait for the wallet button to be enabled for clicking
wallet_button = driver.find_element(By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button')
wallet_button.click() #click that wallet button
#time.sleep(1)
wallet_options = driver.find_elements(By.XPATH, "//*[@data-testid='WalletSidebar--body']//li")
for i in wallet_options:
    if "MetaMask" in i.get_attribute('innerText'): #find the MetaMask wallet button
        i.click() #click the MetaMask wallet button

The problem I noticed when testing this program was that after clicking the MetaMask wallet button via automation, the expected Metamask Notification window was never displayed, and the current window kept loading that button eternally as shown below:

problempreview1

However, if the user manually clicked the same MetaMask wallet button in the same chrome instance, the Metamask Notification window would immediately appear as expected, asking the user to log in for then connecting the wallet to that site, as shown below:

expected_result1

I even checked if there was another hidden window handle after pressing the MetaMask wallet button (via automation) with this code, but there was nothing else:

for handle in driver.window_handles:
            if handle != initial_page:
                login_page = handle
                driver.switch_to.window(login_page)

So, I'm confused, why does that button apparently only work when a user presses it but not when a program does? As always, I'd appreciate a lot if someone could explain what's happening and how could I fix this?


Solution

  • I figured it out already, and it was a foolish thing, I simply had to add the extension path (which must be compressed as a .crx file) as an argument to Selenium's Options(), here's the improved code:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.chrome.service import Service
    
    opt.add_argument('--user-data-dir='+r'C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data') #Add the user data path as an argument in selenium Options
    opt.add_argument("--profile-directory=Default") #Add the profile directory as an argument in selenium Options
    extension_path = r'C:\Users\ResetStoreX\AppData\Local\Google\Chrome\User Data\Default\Extensions\nkbihfbeogaeaoehlefnkodbefgpgknn\10.8.1_0.crx' #assign the extension path of the compressed Metamask extension to this variable
    opt.add_extension(extension_path) #add the extension_path as argument
    
    s = Service(r'C:\Users\ResetStoreX\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe') #Use the chrome driver located at the corresponding path  
    
    driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions
    driver.implicitly_wait(10)
    driver.get('https://opensea.io/') #go to the opensea main page.
    
    initial_page = driver.current_window_handle  #make the previous page the current one
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button'))) #wait for the wallet button to be enabled for clicking
    wallet_button = driver.find_element(By.XPATH, '//*[@id="__next"]/div/div[1]/nav/ul/div[2]/li/button')
    wallet_button.click() #click that wallet button
    #time.sleep(1)
    wallet_options = driver.find_elements(By.XPATH, "//*[@data-testid='WalletSidebar--body']//li")
    for i in wallet_options:
        if "MetaMask" in i.get_attribute('innerText'): #find the MetaMask wallet button
            i.click() #click the MetaMask wallet button
    

    So when you compile the enhanced code, it generates the following output:

    solution1

    Something I noticed was that this program ended up opening a chromedriver tab and a new window to access the Metamask wallet (ie both things are used for the same thing).

    If anyone figures out how to prevent the MetaMask tab from opening as shown in the image, please let me know in the comments.