-->

Detecting Drop down with Selenium WebDriver

2019-07-14 04:51发布

问题:

http://i.stack.imgur.com/L4WUv.jpg

Link to Grid

I'm trying to detect the different drop downs on this page (depicted by the filters by the text boxes). The problem i'm having is that it seems that the filters all have the same ids. I can get the webdriver to find the initial filter button but not target the options in the drop down.

  • Note the filters I'm talking about are the ones from the funnel buttons. For example contains, isEqual, between etc *

This is wrong but an example

it('Should filter grid to -contain Civic', function() {
    browser.element(by.id('ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl03_FilterTextBox_Model')).sendKeys("civic");
    browser.element(by.id('ctl00$ContentPlaceHolder1$RadGrid1$ctl00$ctl02$ctl03$FilterTextBox_Model')).click(); 
    browser.element(by.xpath("//*[contains(text(), 'Contains')]")).click();
})

回答1:

NOTE The answer that was being looked for is at the bottom of this answer after the word "EDIT". The rest of this answer is retained because it is still useful.

It's a challenge to test webpages that dynamically generate ids and other attributes. Sometimes you just have to figure out how to navigate the stable attributes with an xpath. Here's an xpath that finds all four dropdowns:

//tr[@class='rgFilterRow']//input

To differentiate between each one, you can do this:

(//tr[@class='rgFilterRow']//input)[1]      // Brand Name
(//tr[@class='rgFilterRow']//input)[2]      // Classification
(//tr[@class='rgFilterRow']//input)[3]      // Transmission
(//tr[@class='rgFilterRow']//input)[4]      // Fuel

Using numbers to specify elements in an xpath isn't really desirable (it will behave incorrectly if the order of columns in the table changes), but it's probably the best you can do in this case because of all the dynamic ids and general lack of reliable identifying attributes.

EDIT

I misunderstood what you were trying to get because I didn't look at the image that you linked to. Once you've opened up that menu, you should be able to use an xpath to get whichever option you want by the text. For example, if you want the "Contains" option:

//a[@class='rmLink']//span[text()='Contains']


回答2:

This page is highly dynamic. You had better brush up on your XPath, as nothing else will be able to help you. You can use this: http://www.zvon.org/xxl/XPathTutorial/General/examples.html .

Here is a simple example of how to access the Brand Name "pulldown". This is written in Groovy, which looks a lot like Java. If you know Java you should be able to get the idea from this:

WebElement brandName = driver.findElement(By.id("ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl03_BrandNameCombo_Arrow"))
brandName.click()   // to open the "pulldown"
List<WebElement> brandItems = driver.findElements(By.xpath("//ul[@class='rcbList']/li"))
brandItems.each {
    if(it.text == 'BMW')
        it.click()
}

Unfortunately, the above id is not very reliable. A much better strategy would be something like:

WebElement classification = driver.findElement(By.xpath("//table[@summary='combobox']//a[contains(@id, 'ClassificationCombo_Arrow')]"))

Selecting its items is done similarly.

classification.click()  // to open the "pulldown"
List<WebElement> classificationItems = driver.findElements(By.xpath("//ul[@class='rcbList']/li"))
classificationItems.each {
    if(it.text == 'Sedan')
        it.click()
}

If you are not up to the task, you should be able to get help from your development colleagues on how to locate all the elements in this page.