2016-09-14 15 views
2

我有一個網站,其中<select>有超過100個<option> s在其中,每個國家在世界上。我的測試需要選擇一個。我目前的解決方案 - 大約需要2.5秒左右。我希望它快得多。 如何使用Haskell和webdriver從下拉列表中快速選擇一個選項?

findChildrenByLabel :: (WD.WebDriver m, MonadIO m) => 
    Text -> Text -> m [WD.Element] 
findChildrenByLabel label tagName = do 
    parentEl <- findFieldByLabel label 
    WD.findElemsFrom parentEl $ WD.ByTag tagName 

findChildByLabelF :: (WD.WebDriver m, MonadIO m) => 
    Text -> Text -> (WD.Element -> m Bool) -> m WD.Element 
findChildByLabelF label tagName f = do 
    children <- findChildrenByLabel label tagName 
    child <- filterM f children 
    liftIO $ child `shouldSatisfy` ((==1) . length) 
    return (headEx child) 

selectDropdownByLabel :: (WD.WebDriver m, MonadIO m) => Text -> Text -> m() 
selectDropdownByLabel label optionName = do 
    targetOption <- findChildByLabelF 
    label "option" (\el -> (== optionName) <$> WD.getText el) 
    WD.click targetOption 

我在爪哇發現this SO answer,但似乎並沒有像Selenium.SupportSelectByText Haskell的東西。

+2

由於提取了'WD.findElemsFrom'中的所有選項,可能會使用動態生成的XPath表達式(比如''//選項[contains(text(),'SomeOption')]''')更快地定位特定選項。看起來它會節省多次調用「WD.getText」。 – danidiaz

回答

0

基於danidiaz的回答,我寫了這個:

findFieldByLabel :: (WD.WebDriver m, MonadIO m) => Text -> m WD.Element 
findFieldByLabel str = do 
    labels :: [WD.Element] <- WD.findElems $ WD.ByXPath $ 
    "//label[text() = \"" <> str <> "\"]" 
    els <- catMaybes <$> mapM (`WD.attr` "for") labels 
    liftIO $ els `shouldSatisfy` ((==1) . length) 
    WD.findElem $ WD.ById $ headEx els 

selectDropdownByLabel :: (WD.WebDriver m, MonadIO m) => Text -> Text -> m() 
selectDropdownByLabel label optionName = do 
    field <- findFieldByLabel label 
    targetOptions <- WD.findElemsFrom field $ WD.ByXPath $ 
    "option[text() = \"" <> optionName <> "\"]" 
    liftIO $ targetOptions `shouldSatisfy` ((==1) . length) 
    WD.click $ headEx targetOptions 

我用這樣的:

selectDropdownByLabel "Country of residence" "United States" 

原來的解決方案花了大約2.5秒,這大約是0.16。大改進,謝謝danidiaz!

相關問題