'How can I automate opening a Dash dbc.AccordionItem (tab) using Selenium in Python?
I’ve been trying to automate the testing of my app with Python Selenium.
The app sits entirely inside a Python Dash dbc.Accordion.
There are three dbc.AccordionItem elements (or tabs).
My app takes a culinary recipe as a block of text and returns a nutritional profile.
The beta version is published as a Docker Image on Amazon AWS Elastic Container Services. My work has focused on my local code, run on a local host, which is identical to the app published online.
If you wish to view the source code, the IP address and guest credentials are below.
The Selenium code works fine until I need to uncollapse the second dbc.AccordionItem.
To keep this brief as possible, I cannot figure out how to uncollapse the second tab and click the submit button using Python-Selenium. I need to be able to click on the tab's header or banner to uncollapse it or I need another way to open the dbc.AccordionItem (tab).
I should be able to access the element in a number of ways (via id, class name, xpath, link etc...).
But my attempts have failed.
I have received several error messages.
The two most common are as follows:
"Unable to locate: <selenium.webdriver.remote.webelement.WebElement"
Or it rejects the coordinates when I am able to access it with xpath:
"selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable at point (759, 751)"
(This seems to happen because the AccordionItem is a moving target, but I'm not sure).
Does anyone have any idea how to solve this problem?
Thank you for reviewing my question.
Your feedback is appreciated.
This is the IP address and credentials. http://44.201.177.119:8050/
username: guest
password: guestpass
Here is my Selenium code so far, less than one page long.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
service = Service(PATH)
driver = webdriver.Chrome(service=service)
driver.maximize_window()
driver.get("http://localhost:8050/")
title = driver.title
print("Connected to Web Page: ", title)
# Find recipe textarea
try:
recipe_textarea = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "recipe-textarea")))
finally:
pass
# Get and load test or training data.
recipe_textarea.send_keys("2 cups lentils")
# Find text area submit button (first tab).
try:
submit_button = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "recipe-textarea-submit-button")))
finally:
print("Located: ", submit_button)
pass
# Click button to submit recipe data (first tab).
submit_button.click()
try:
submit_edits = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//button[normalize-space()='Step 2: Edit Initial Results']")))
except:
print("EXCEPTION: Cannot find Accordion Item.")
finally:
submit_edits.click()
Here is a snapshot of the HTML code from my desktop.
I cannot find out whether or not the "flex" badge is part of the problem.

What did I try?
I exhausted all the online documentation I could find. I read the one complete guide to Selenium I could find on Amazon. I have asked the question posted on two other forums, including the Dash-Plotly community forum, where my question is one of only a handful related to the topic. I have tried guided projects on Coursera, but resources are limited. I believe I have reviewed the Stack Overflow questions on the topic.
I downloaded and read the "pytest-test" documentation, and I lost of count of how many YouTube tutorial I followed, though there's little to none that specifically addresses how to identify html elements in an accordion component. As noted in my summary, I have been trying to locate the accordion's second tab header (banner) by id, class_name and link_text so I can open it.
I have tried for roughly three days, but my attempts have failed.
What was I expecting?
I had hoped to open the second accordion tab, entitled "Step 2: Edit Initial Results", so I could click on the Submit Edits button after Step One was completed.
In Step One, the user pastes a recipe into the text area and clicks the Submit button. In Step Two, the user reviews the initial results and can make changes if needed, then clicking the Submit Edits button.
In Step Three, the user views the final results - a nutritional profile tracking more than 40 nutrients. Right now, I am trying to prepare the local code to process several thousand lists of ingredients for testing purposes.
Solution 1:[1]
I am not entirely sure how or why.
But I found a working solution in Javascript to the problem preventing me from automating the opening of the second AccordionItem (banner or tab) in a Dash-Python dbc.Accordion. For some reason, you cannot use the standard Python-Selenium variable.click() method. Please see code under # Find second header banner by xpath and click.
Here is the code:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
service = Service(PATH)
driver = webdriver.Chrome(service=service)
driver.maximize_window()
driver.get("http://localhost:8050/")
action = ActionChains(driver)
# Confirm connected to web page:
page_title = driver.title
print("Connected to Web Page: ", page_title)
time.sleep(5)
# Find recipe text area.
recipe_textarea = driver.find_element(by=By.ID, value='recipe-textarea')
# Load test data into recipe text area.
recipe_textarea.send_keys("2 cups lentils")
# Find submit button
submit_recipe = driver.find_element(
by=By.ID, value='recipe-textarea-submit-button')
# Click submit button.
submit_recipe.click()
# Scroll down to element
driver.execute_script("window.scrollBy(0,500)", "")
# Find second header banner by xpath and click
tab_two = driver.find_element_by_xpath(
"//button[normalize-space()='Step 2: Edit Initial Results']")
driver.execute_script("arguments[0].click();", tab_two)
# Find submit edits button.
submit_edits = driver.find_element_by_id(
"nutrients-review-datatable-submit-button")
# Click submit edits button
submit_edits.click()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
