6

I am aware that Selenium apparently doesn't support navigating context menus. But I have also seen in several other threads that there is a work-around by using action chains. Using context_click() followed by arrow key commands to navigate through the menus.

All examples I've seen have used Java, and when I translated to Python, only the context_click() command would register. Strangely enough, I wouldn't get an error either. Other sources have said that the context menus Selenium produces are only system level, and thus, Selenium cannot touch them, only create.

So my question is, has anyone been able to successfully navigate and chose options from context menus through Selenium? Python examples are preferred, but I'll take any advice or answers I can get.

Edit:

Code:

driver.get('https://www.google.com/')
actionChains = ActionChains(driver)
actionChains.context_click().send_keys(Keys.ARROW_UP).send_keys(Keys.ENTER).perform()

Context:

This is just a test script that I have been running to test this situation. In my personal project, I need to navigate the context menu to access a chrome extension. Since selenium can only interact within the web page I can't have it click on the button for the Chrome extension that is displayed by the browser. So this is the work-around I have been attempting.

Research:

https://testingrepository.com/how-to-right-click-using-selenium-webdriver/ - This source tells that seleniums context menus are only system level. In Java examples they also use a .build() command. As far as my knowledge, this command is not available to Python.

Select an Option from the Right-Click Menu in Selenium Webdriver - Java - Thread suggesting that arrow key commands should work. However, all examples use Java and the .build() command as well

https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/common/action_chains.py - shows that ActionChains() are Pythons's version of a .build() command. Might be common knowledge to some. I did not know this prior.

How to perform right click using Selenium ChromeDriver? - very similar question to mine. While one user suggests that the menu cannot be interacted with, another suggests the actionChains work-around will work.

Wheat-Thin
  • 61
  • 1
  • 4
  • @DebanjanB Edited. Thank you – Wheat-Thin Aug 21 '17 at 18:31
  • As explained here - http://elementalselenium.com/tips/63-right-clickFurther - right click menus are often system level menus untouchable by selenium. More discussion here: https://github.com/GoogleChrome/puppeteer/issues/1575 – kchak Mar 08 '18 at 04:24
  • Were you able to find a solution for this with only selenium? I am stuck in a similar situation. – Ontropy Feb 07 '22 at 01:25
  • @Ontropy The last time I worked on this was years ago. However from what I remember the other commenters/answers are correct. Selenium only interfaces with the web page and that’s it. It can’t even interface with a browser’s UI (like back buttons) or OS level UI (like context menus). For this reason you should look at other tools to accomplish navigating context menus. Workarounds exist like mentioned in other answers. However, these are OS dependent. – Wheat-Thin Feb 08 '22 at 04:54

4 Answers4

8

Thin,

I had the same problem and wonder nobody answered this already... It wasn't possible for me to solve it with selenium, cause selenium would navigate within the page. My solution:

import win32com.client as comclt
wsh= comclt.Dispatch("WScript.Shell")
ActionChains(driver).move_to_element(element).context_click().perform()
wsh.SendKeys("{DOWN}") # send the keys you want
  • +1 for the answer. I've tried this workaround and it works. Although it is system-dependent (windows only solution) and has gotcha (not working on headless mode, browser should be in foreground and maybe etc), it should be accepted answer for operating context menu. – imckl Nov 29 '19 at 08:13
0

Well we can solve this using selenium along with pyautogui. The reason for using pyautogui is that we need to have control of the mouse for controlling the options on the context menu. To demonstrate this, I am going to use a python code to automatically open a google image of Avengers Endgame in new tab.

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
import pyautogui

URL = 'https://www.google.com/'
PATH = r'C:\Program Files (x86)\chromedriver.exe'

driver = webdriver.Chrome(PATH)
action = ActionChains(driver)
driver.get(URL)

search = driver.find_element_by_name('q')
search.send_keys('Avengers Endgame')
search.send_keys(Keys.RETURN)

image_tab = driver.find_element_by_xpath('//a[text()="Images"]')
image_tab.click()

required_image = driver.find_element_by_xpath('//a[@class="wXeWr islib nfEiy mM5pbd"]')
action.context_click(required_image).perform()
pyautogui.moveTo(120, 130, duration=1)
pyautogui.leftClick()
time.sleep(1)
pyautogui.moveTo(300,40)
pyautogui.leftClick()

Now in the above code, the part till pyautogui.moveTo(120, 130, duration=1) is selenium based. Your answer begins from pyautogui.moveTo(120, 130, duration=1) and what this does is simply moves the mouse button to the open image in new tab option of the context menu(Please note that the screen coordinates may vary based on your screen size). The next line clicks the option(using action.click().perform() won't work as expected).

The next two lines helps in navigating to the tab after it opens. Hope the code helps!

Aknk
  • 336
  • 3
  • 14
0

In python and selenium 4.2 you just need to store your navigation handle:

currently_handle = navegador.current_window_handle
driver.switch_to.window(currently_handle).

This will put your current window in the foreground!

Ajeet Verma
  • 2,938
  • 3
  • 13
  • 24
-1

one way to work around this I think at least in java is to perform those actions with one instance of the class Robot.

This is just an example of handling authentication in chromme. Is very usefull when I need to perform actions out the selenium scope.

try{
        Robot bot = new Robot();

        for(char c: userArray){
            bot.keyPress(c);
            bot.keyRelease(c);
            bot.delay(300);
        }
        bot.keyPress(KeyEvent.VK_TAB);
        bot.keyRelease(KeyEvent.VK_TAB);

        for(char c: userArray){
            bot.keyPress(c);
            bot.keyRelease(c);
            bot.delay(300);
        }

        bot.keyPress(KeyEvent.VK_ENTER);
        bot.keyRelease(KeyEvent.VK_ENTER);

    }catch(Exception e){
        e.printStackTrace();
    }
Dharman
  • 30,962
  • 25
  • 85
  • 135