I am using Selenium to write unit tests for a website to test scientific software. The backend uses Flask to generate a sidebar where each project is clickable with a dropdown menu. You can only open one of the project tabs at once.
I want to loop through the projects in this sidebar and verify that following each of this links generates the correct message (this could be a 403). I am new to Selenium.
This is a MWE of the compiled HTML from Flask (it's quite condensed so please forgive any syntax errors)
<!-- One element from the list -->
<li class="treeview"> <!-- Main Heading -->
<a href="#">
<i class="fa fa-code"></i>
<span name='lst_project_name'>Project1</span>
</a>
<ul class="treeview-menu"> <!-- Submenu, visible when clicked -->
<li><a href="https://git.example.org/project1/code">Gitlab (External)</a></li>
<li><a href="/4/edit">Edit Project</a></li>
<li><a href="/4/new_test_session">Submit New Test</a></li>
</ul>
</li>
<!--- And a second (its identical) -->
<li class="treeview">
<a href="#">
<i class="fa fa-code"></i>
<span name='lst_project_name'>Project1</span>
</a>
<ul class="treeview-menu">
<li><a href="https://git.example.org/project1/code">Gitlab (External)</a></li>
<li><a href="/4/edit">Edit Project</a></li>
<li><a href="/4/new_test_session">Submit New Test</a></li>
</ul>
</li>
At the moment I am interested in the 'Submit New Test' button, but it is hidden until I click on the project. I think I would like a loop of the form
listed_projects = driver.find_elements_by_name("lst_project_name")
for project in listed_projects:
project.click()
el = driver.find_element_by_xpath("//a[contains(text(),'Submit New Test')]")
el.click()
heading1 = driver.find_element_by_tag_name('h1')
self.assertEqual(heading1.text,'Not Allowed')
driver.back()
But this won't work for a few reasons, my main tripping point is that the xpath simply finds the first element. Is there any way to get xpath to search relative to a clicked element? I could use a list elements returned by an xpath query, but then the element I need to click isn't visible.
Also, once I leave the webpage, how do I access the second item in the list.
This question is pretty similar, Click submenu which is dynamicly visible in Selenium WebDriver, I liked the arrow keys solution, but, they don't work in my case. I can edit the source html to fit the test.
1 Answer 1
You can locate whole list of elements (like all <li>
elements inside treeview_menu class, using CSS locators), loop over them, test other attributes (like .text
), and .click()
on the item you want. I do it all the time, it is much more robust than creating and maintaining complex XPATH expressions.
You can edit source. Give all submenu items the same name: easy to locate, easy to loop over.
With python, you can drop to debugger with just single line import pdb;pdb.set_trace()
just after you located the list, so you can poke around to see what was located and how useful it was. This speeds the code development immensely: I don't waste time crafting XPath, I prefer to spend time in Python, which I mastered to higher level. I love Python, because it saves me lots of time.
BTW what you are writing are UI/integration/system tests. Real unit test will test the internal calls to the system libraries, and you should spend 80% of time on those, as explained recently in answers about test pyramid
-
To expand in case anyone else gets stuck on here I used a common name for each submenu and a unique ID. By finding all elements with a name and then storing their ID's I was able to later find the element I was working with once the page had refreshed.Aaron– Aaron2018年04月24日 16:16:28 +00:00Commented Apr 24, 2018 at 16:16
-
@Aaron - exactly. Much more robust than complicated Xpath, isn't it?Peter M. - stands for Monica– Peter M. - stands for Monica2018年04月24日 17:10:26 +00:00Commented Apr 24, 2018 at 17:10
Explore related questions
See similar questions with these tags.