如何使用LINQ在C#中查找嵌套的selenium WebElement?

时间:2017-03-06 13:41:26

标签: c# linq selenium

我一直在学习LINQ,并尝试将其应用于使用selenium在页面上查找某些Web元素。

我有一个角度网站,显示由div组成的表格。列中的所有行(包括标题)具有相同的属性(例如,css选择器/类名等)。

我想找到列中可见的所有输入框,并想出了这个......

var applyBoxes2 = from box in driver.FindElements(By.CssSelector("div.col-apply.col-md-1"))
                  where box.Text != "Apply?"
                  select box;

var clickableBox = from box in applyBoxes2
                   where box.FindElement(By.TagName("input")).Displayed == true
                   select box.FindElement(By.TagName("input"));

第一个查询是必需的,因为第一行是标题,并且不包含输入字段。如果我没有这个查询,我的第二个查询将在尝试执行findelement =“input”时失败。

有人知道我是否可以合并这两个陈述?所以首先我会过滤掉标题,然后我会在每个div中找到每个输入框。

对于如何改进这一点的任何想法都会受到欢迎。

非常感谢,

3 个答案:

答案 0 :(得分:3)

使用&&运算符,当它没有通过第一个语句时会短路。因此,在您的情况下,如果文本为Apply?,则不会尝试查找元素。

var clickableBox = from box in driver.FindElements(By.CssSelector("div.col-apply.col-md-1"))
                              where box.Text != "Apply?" && box.FindElement(By.TagName("input")).Displayed == true
                              select box.FindElement(By.TagName("input"));

答案 1 :(得分:1)

您可以使用let子句, 执行内部条款。

代码将是这样的:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title></title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
  <script src="https://unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myController">

  <ul>
    <li><a ui-sref="dashboard.view0({item: 'item0'})">item0</a></li>
    <li><a ui-sref="dashboard.view0({item: 'item1'})">item1</a></li>
    <li><a ui-sref="dashboard.view0({item: 'item2'})">item2</a></li>
    <li><a ui-sref="dashboard.view0({item: 'item3'})">item3</a></li>
    <li><a ui-sref="dashboard.view0({item: 'item4'})">item4</a></li>
  </ul>

  <ul>
    <li><a ui-sref="dashboard.view0">view0</a></li>
    <li><a ui-sref="dashboard.view1">view1</a></li>
  </ul>
  <div class="" ui-view>

  </div>

  <strong></strong>
  <div class="">
    you are looking at <strong>{{$state.current.name}}</strong> of {{$state.$current.params.item.value()}}
  </div>
  <script type="text/javascript">
    angular
      .module('myApp', ['ui.router'])
      .config(function($stateProvider, $urlRouterProvider) {
        $stateProvider
          .state('dashboard',{
            url: '/dashboard/:item',
            params: {item: 'item0'},
            controller: 'myController as vm',
            abstract: true,
          })
          .state('dashboard.view0',{
            url: '/view0',
            templateUrl: 'view0.html',
            controller: 'myController as vm'
          })
          .state('dashboard.view1',{
            url: '/view1',
            templateUrl: 'view0.html',
            controller: 'myController as vm'
          });

      })
      .run(function($rootScope, $state){
        $rootScope.$state = $state;
      })
      .controller('myController', function($scope){
          $scope.items = [{'image': '','name':'item0', 'alt': 'item0_logo'},
              {'image': '','name':'item1','alt': 'item1_logo'},
              {'image': '','name':'item2','alt': 'item2_logo'},
              {'image': '','name':'item3','alt': 'item3_logo'}];
      });
  </script>

  <script type="text/ng-template" id="view0.html">
    <h2>This is view0</h2>
  </script>
  <script type="text/ng-template" id="view1.html">
    <h2>This is view1</h2>
  </script>
</body>
</html>

答案 2 :(得分:1)

你可以做这样的事情

var clickableBox = driver.FindElements(By.CssSelector("div.col-apply.col-md-1"))
    .Where(box => box.Text != "Apply?")
    .Select(box => box.FindElement(By.TagName("input")))
    .Where(boxElement => boxElement.Displayed);