Just a heads up, this is my first post on here so if I violate any of the posting rules please let me know!
Currently, I am attempting to :
- Find WebElements(Hyperlinks) in a Dashboard Table to create a list of links.
- Iterate through that list, clicking on the # 1 link first.
- Once the first link is clicked, execute several clicks using
find_element_by(' ' ).click()
that filter the data first, and then leads to a "Save As" button that downloads data I need. - Wait for the file to download.
- Go on to the Next Page(of the # 1 link), and click "Save As".
- Repeat until no more pages.
- Go Back to Dashboard Table and Click on next Link(#2) and repeat #3-6.
- Go to Next page of Dashboard Table, and repeat #1-7.
Now, my question pertains more to design/approach. Should I use nested loops to accomplish the iterations? Should I use a class since I have several iterations going on that will eventually have to refer to each other?
Here's my code
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
import selenium.webdriver.support.ui as UI
from selenium.webdriver.support import expected_conditions as EC
import time
"Use random var for the interval between clicks"
"Identify authorization credentials "
baseurl = "myUrl"
username = "myUser"
password = "myPass
xpaths = {'usernameTxtBox': "//*[@id='Username']",
'passwordTxtBox': "//*[@id='Pass']",
'submitButton': "//*[@id='LogIn']",
'DashboardTableButton': "//*[@id='DashboardTable"
}
mydriver = webdriver.Chrome(
executable_path='AppData\\Local\\Programs\\Python\\Python36-32\\Scripts\\chromedriver.exe')
mydriver.get(baseurl)
mydriver.maximize_window()
"Write Username"
mydriver.find_element_by_xpath(xpaths['usernameTxtBox']).send_keys(username)
"Clear Password TextBox"
mydriver.find_element_by_xpath(xpaths['passwordTxtBox']).clear()
"Write Password"
mydriver.find_element_by_xpath(xpaths['passwordTxtBox']).send_keys(password)
"Click Login Button"
mydriver.find_element_by_xpath(xpaths['submitButton']).click()
"Wait to click"
mydriver.implicitly_wait(4)
"Click Button that leads to Dashboard"
mydriver.find_element_by_xpath(xpaths['DashboardTableButton']).click()
"It is HERE where I am conceptually stuck"
mydriver.implicitly_wait(6)
list_of_links = mydriver.find_elements_by_tag_name('h4') # Identify all the Links in the DashboardTable (there are 10 in each page)
for links in enumerate(list_of_links) :
mydriver.implicitly_wait(4)
for link in enumerate(links):
link.click()
"Filter data"
mydriver.find_element_by_xpath('//*[@id="status-wrapper"]/div/ul/li[3]/button').click()
mydriver.find_element_by_xpath('//*[@id="header-bar-project-table"]/dt[1]/button').click()
mydriver.find_element_by_xpath('//*[@id="filter-modal-content"]/li[1]/ul/li[2]/fieldset/h4/legend/button').click
mydriver.find_element_by_xpath('//*[@id="search-facet-input-excludeActivities-true"]').click
mydriver.find_element_by_xpath('//*[@id="search-facet-input-activityType-E"]').click
mydriver.find_element_by_xpath('//*[@id="activityTimespan"]').click
mydriver.find_element_by_xpath('//*[@id="activityTimespan"]/option[5]').click
mydriver.find_element_by_xpath('//*[@id="dialog"]/div/div[2]/div/p/button[1]').click
"Save As"
mydriver.find_element_by_xpath('//*[@id="all-checkbox"]').click
mydriver.find_element_by_xpath('//*[@id="bulk-actions-bar"]/li[7]/button').click()
mydriver.implicitly_wait(6)
mydriver.quit()
Also, I'm aware that I still have to incorporate pagination for both loops.
Thanks and I truly appreciate any input/thoughts/ideas/suggestions!
1 Answer 1
Some of the code snippets may not be 100% (been awhile since I've used python) but the content and intent is the same. I recommend not doing an implicit wait, but find the last element to load on the page and wait for that...or just wait for the list you want. I typically utilize the org.openqa.selenium.support.ui.WebDriverWait wait = new org.openqa.selenium.support.ui.WebDriverWait (driver, 15)
where the 15 is seconds before it's a timeout. pull your list of elements. you can paginate after you get a list and then repeat to the end. Optionally you can also pull the full html and query it directly to get the list of nodes you want to utilize.
Pull the elements using xquery with the //a
you said they were all hyperlinks. I'm guessing that they all have a similar class, if so you can use that driver.findelements(By.xpath('//a[@class='hyperlinkclassname']))
This will return a list of webelements that can be parsed like any other list.
At this point I would call a sub-test in the form of a class with methods or just the methods that has what you want to do on each page. Based on your description each hyperlink loads a page with similar controls on it. If that is so you can have the same steps and maybe pass a few parameters to the method where you are executing those steps.
You may want to capture the URL of the page when you are on the dashboard table and then just re-navigate to that page. Or if you have breadcrumbs you can do that for navigation.
Your "repeat 1-7" looks like another level of abstraction. Start at the bottom level and build each layer and then nest those in classes with methods that are called as you loop each parent layer. Your test just calls the top most parent layer and then the rest is done in the other layers of abstraction.
If you have some additional issues please put some html structure up for how your site actually is rendered. Currently you just have your code which we can't see the structure of the site itself on.
list_of_links = mydriver.find_elements_by_tag_name('h4')
. Def need to change the element which I'm searching by.