I'm working on my first-ever Selenium Python project and am baby stepping through it. I have an inconsistent issue and want to see if there's a better way to code it.
I need to select "Active" from a drop-down menu. I'm selecting the drop down input element and clicking on it. This will open a child element of the input with the list items in it. Here's where the problem lies...sometimes the drop down element stays open and I can select "Active" and everything works great. Sometimes, however, the drop down element opens and closes immediately before I can pick "Active". I'm currently trying to sleep for 3 seconds after clicking on the input element, hoping that will solve the issue. It seemed to for a little while, but now then it will revert back to closing immediately.
So is there a better way to open this drop down box and select active?
#select the status drop down box and click to open it, wait 3 seconds to make sure it loads
#and select the 'A'ctive list item and click to select it
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "input-w_112"))).click()
time.sleep(3)
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "w_113"))).find_element(By.XPATH, '//*[#combovalue="A"]').click()
Sometimes the list items box will stay open, sometimes it closes immediately.
You can do this task with executing a JS script from Selenium WebDriver.
Select the drop-down menu you need.
Select an option by its index.
Code
JS_script = """
var menu = document.getElementById("menu");
menu.selectedIndex = 0;
"""
driver.execute_script(JS_script)
Related
I am trying to get data from a Power Bi table. There are some elements that appear when hovering over a table. When I right click on ... I don't see Inspect Element. However, when I left click on this element, I can see a menu, and if I right click on any items, I can see Inspect element.
My first question, is why I don't see Inspect Element in the right click menu for all elements in the browser. Am I somehow able to open this ... menu programmatically in Selenium?
the Export Data element only appears in HTML after the first left click. I'm assuming this is created using Javascript and in order to export data with Selenium I would have to programmatically instantiate this by clicking on the ... menu. Is selenium capable of triggering javascript functions that generate more html code in a dynamic webpage? Or do I need to somehow click on the ... element.
If I can execute a javascript function, how can I find out in Edge the javascript function that gets executed and how can I replicate this function in Selenium
Essentially, if I try to find the Export data element in Selenium, it is not able to find it, unless I set a breakpoint before search, then in EdgeDriver I open this menu, and then I can find it and click it through Python
If all else fails, can I programmatically open the left click menu by automating a mouse click at certain coordinates in Selenium?
1.1 why I don't see Inspect Element in the right click menu for all elements:
PowerBi has its own context menu so they suppress the browsers context menu. If the element is tricky to find the dev tools, you can press Ctrl + Shift + C (while dev tools is open) and then click the desired element. Your mouse needs to be already over the element before pressing the key combination.
1.2 Am I somehow able to open this ... menu programmatically in Selenium?
Seems a little tricky, but could work if you first find the title of that area and move the mouse there, like described here: https://stackoverflow.com/a/8261754/12914172
Then your element should be in the html and you can find it hopefully by its class name vcMenuBtn that seems to be unique on that page. But you need to verify that.
2. Is selenium capable of triggering javascript functions that generate more html code in a dynamic webpage? Or do I need to somehow click on the ... element.
Selenium is able to execute javascript like desribed here: https://stackoverflow.com/a/70544802/12914172
However in your sample, and I was quickly checking the PowerBI online page, this looks like a whole lot of reverse engineering to understand and can sometimes be dangerous as well. I would go for hoover over the area find the ... and click it.
3. How can I find out in Edge the javascript function that gets executed
In dev tools you can set breakpoints to debug the steps the pages does after an action. But again, I would not invest to much time in that.
4. Can I programmatically open the left click menu by automating a mouse click at certain coordinates in Selenium?
Yes but this never works as good as the way described above. If you still want to give it a try, maybe that answer helps: https://stackoverflow.com/a/26385456/12914172
Many thanks to r000bin, this solution works for me, downloading data from PowerBI using Selenium for Python:
import selenium, mouse, time
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
url = 'https://dataport.gasunie.nl/Vulling-Gasopslagen-Nederland'
driver = selenium.webdriver.Chrome(service=Service())
driver.get(url)
time.sleep(4)
#driver.fullscreen_window()
#driver.switch_to.window(driver.current_window_handle)
time.sleep(4)
iframe = driver.find_elements(By.TAG_NAME, 'iframe')
assert len(iframe)==1
driver.switch_to.frame(iframe[0])
time.sleep(4)
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
actions.move_to_element_with_offset(driver.find_element(By.TAG_NAME, 'html'), 0,0)
actions.move_by_offset('5', '5').click().perform()
time.sleep(4)
button = driver.find_element(By.CLASS_NAME, 'vcMenuBtn')
button.click()
button = driver.find_element(By.ID, '0')
button.click()
# 4 tabs and 1 enter
time.sleep(4)
for n in range(4):
element = driver.switch_to.active_element
time.sleep(2)
element.send_keys(Keys.TAB)
time.sleep(2)
element = driver.switch_to.active_element
time.sleep(2)
element.send_keys(Keys.ENTER)
driver.close()
I am writing a script right now to take information from a website and there is a lot of select/option fields. The problem is, currently I am checking to see if the select box is clickable before trying to click the options but this works about 15% of the time. Here is the line that waits for the element to be clickable:
schoolbox = Select(WebDriverWait(driver, 100).until(EC.element_to_be_clickable((By.ID, "clCampusSelectBox"))))
How do I wait for the options below this select element to be clickable?
Thanks
Edit: here are the dropdowns: https://shop.bookstore.ubc.ca/courselistbuilder.aspx
Clickable element has to be visible and enabled. The <option> elements under the <select> are usually not visible, so "is clickable" check will fail. I suggest you wait for the dropdown to be visible and then use select class to select the option
schoolbox = Select(WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "clCampusSelectBox"))))
schoolbox.select_by_value("someValue")
I am writing this to inform you that waiting for select_list and waiting for options are two different thing! Why are you waiting for select_list to be clickable? You need to wait for option,right? I don't know python, I am using WATIR(language is Ruby) where waiting for select_list and then waiting for option will automatically happen, you don't have write anything
This simple code is enough
b.select_list(:id,'q').select 'hi'
It will automatically wait for select list to be present and then it will wait for option to be present, you don't have to do anything deliberately.
But if I want to write the code to wait for select_list, then I will write
b.select_list(:id,'q').wait_until_present.select 'hi'
If I want to write the code to wait for option in the select_list then I will write
b.select_list(:id,'q').option(:text,'hi').wait_until_present.select
If I want to wait for both, then I will write
b.select_list(:id,'q').wait_until_present.option(:text,'hi').wait_until_present.select
but these are not necessary in WATIR because it automatically waits for everything.
So all you need to know is whether to wait for select_list or to wait for option because in certain condition your select list option will be populated according to some condition.
I'm writing some automated GUI testing with selenium (Python binding + Firefox driver). On this page we're having problem with, there is button that I want to click but it's at the lower part of the page (I'm selecting the button via id). The default size of the Firefox window isn't large enough to show it. So the actual clicked element is one from the tab bar which is always visible.
If I manually resize the window during the test, it runs smoothly.
This looks like a bug to me TBH. I'm wondering if this is a known feature and a work around exists.
You can use Actions Chains to scroll to the element
actions = ActionChains(driver)
actions.move_to_element(element).perform()
That will make the button visible and you will be able to click on it. You can also use explicit wait to make sure the button is visible.
You can call location_once_scrolled_into_view on the element. It is a property that returns the elements location, but it has the added side-effect of scrolling to the element first if it is not in view already.
element.location_once_scrolled_into_view.
there is a list field which I have sticked with an image
Here after clicking on the list , I have to select first option that is Cash(EUR)
I have written a code in python by xpath that is ,
browser.find_element_by_xpath("//Select[#name='journal_id']/option[normalize-space(text())='Cash (EUR)']").click()
from this code , it will let me select that perticular element but not able to click on that element instead of writing click()
So , whats the exact code ? or give me specific code so that I will be able to click on that element
You should use here selenium select command, instead of click. as it is drop down not clickable element.
It may be done by this that first I focus on that list box on which I have to select cash option then I will search an element by keyboard by send_key method & in which I will enter work for ex. Cash , then this process will run automatically like we select an element just like entering their name by a keyboard
a=browser.find_element_by_xpath("html/body/div[6]/div/div/div[2]/div/div/div/div/div/div[2]/div/div[4]/div/div/table[1]/tbody/tr/td[1]/table/tbody/tr[5]/td[2]/span/select")
a.send_keys("Cash (EUR)")
It works :)
Here it will automatically select cash option by not going options view
I've been trying to scrape a site using a PhantomJS/Selenium setup in Python.
There's a dropdown in the page that, when selected, populates the options of another dropdown. When I'm automating this with Firefox, when I select_by_visible_text on the first dropdown, the second one gets populated.
However, the same code doesn't work with PhantomJS.
browser = webdriver.PhantomJS(executable_path=PHANTOMJS_PATH)
## browser = webdriver.Firefox()
wait = WebDriverWait(browser, WAIT_TIME)
browser.get(URL)
Select(browser.find_element_by_id('DropDown0')).select_by_visible_text('XXX')
def condition_wait_for_dropdown(driver):
ret = False
if driver.find_elements_by_xpath('//*[#id="DropDown1"]/option'):
ret = True
return ret
wait.until(condition_wait_for_dropdown)
I have tried using a hard-coded sleep instead of the custom waiting condition, and checked the DOM - the second dropdown never gets populated at all.
Can this be a problem with the webpage itself? If so, how do I work around this?
EDIT: Just to clarify, this works with Selenium+Firefox, so the possibility exists that this is a bug in the PJS driver itself.
I found a fix for this, so best to leave it here for posterity.
I had an input field in the page form, so after selecting the first dropdown I moved the focus to the input field, and sent an ENTER to it. The second dropdown got loaded immediately.
Still don't know wth is wrong with this web page.