首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用Java Selenium JavascriptExecutor访问AngularJS变量

用Java Selenium JavascriptExecutor访问AngularJS变量
EN

Stack Overflow用户
提问于 2018-10-21 01:44:10
回答 1查看 797关注 0票数 5

下面是一个带有AngularJS ng-click属性的div,该属性在单击该div时设置一个变量。

代码语言:javascript
复制
<div id="id"
     ng-click="foo.bar = true;">
     Set bar variable on foo object to true
</div>

下面是一些使用Selenium单击div元素的Java代码。

代码语言:javascript
复制
By upload = By.id("id");
driver.findElement(uploadCensus).click();

当我运行Java代码时,AngularJS永远挂起。我认为foo.bar不是在单击div时设置的,所以这里有一些直接设置变量的代码。

代码语言:javascript
复制
By upload = By.id("id");
((JavascriptExecutor) driver)
    .executeScript("foo.bar = true;",   
    driver.findElement(upload));

堆栈跟踪

未知错误:未定义foo (会话信息: chrome=56.0.2924.87) (驱动程序信息: chromedriver=2.25.426923 (0390b88869384d6eb0d5d09729679f934aab9eed),platform=Windows NT 6.1.7601 SP1 x86_64) (警告:服务器未提供任何堆栈跟踪信息)命令持续时间或超时: 51毫秒构建信息:版本:'2.53.0',修订版:'35ae25b',时间:'2016-03-15 17:00:58‘系统信息:主机:'WV-VC104-027',ip:'{ip}',os.name:‘userDataDir=C:\Users{user}\AppData\Local\Temp\scoped_dir5600_4225},7',os.arch:'amd64',os.version:'6.1',java.version:'1.8.0_151’驱动程序信息: org.openqa.selenium.chrome.ChromeDriver功能{applicationCacheEnabled=false,rotatable=false,mobileEmulationEnabled=false,networkConnectionEnabled=false,chrome={chromedriverVersion=2.25.426923 (0390b88869384d6eb0d5d09929679f934aab9eed),Windows takesHeapSnapshot=true,pageLoadStrategy=normal,databaseEnabled=false,handlesAlerts=true,hasTouchScreen=false,version=56.0.2924.87,,,nativeEvents=true,acceptSslCerts=true,locationContextEnabled=true,webStorageEnabled=true,browserName=chrome,takesScreenshot=true,javascriptEnabled=true,cssSelectorsEnabled=true}会话ID: a7734312eff62fe452a53895b221a58d

当我尝试设置foo.bar时,我无法获得对该变量的引用,因为它不是全局定义的,并且隐藏在AngularJS源代码中的某个地方。我试图解开索引并查找变量,但似乎找不到它。我想通过JavascriptExecutor手动设置foo.bar变量,但无法获得对该变量的引用。如何查找和设置变量?

如果这看起来是触发ng-click的错误方式,我对此持开放态度。我相信Protractor有办法解决这个问题,但这个AngularJS应用程序部署在企业环境中,几个月来一直试图让业务部门批准这项技术。我被硒困住了。救命..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-21 07:01:40

只需直接回答您的问题,不要将其用于您的案例:)

Angular有隔离变量scope.So,你需要得到作用域,并在其中设置变量。

代码语言:javascript
复制
angular.element("#id").scope().foo.bar = true;

但不要把它用在你的情况下。当您在系统级别测试应用程序时,您必须以与用户相同的方式测试它们。

推荐答案:等待java中的角度可测试性

好消息是你可以在expilcit wait中使用JavaScriptExecutor来执行相同类型的javascript。

您的java代码,用于为waitforangular创建预期的condrion

代码语言:javascript
复制
String waitForAngularJs ="Your javascript goes here"; // as it is lengthy read it from file and store here.
ExpectedCondition<Boolean> waitForAngular= new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return ((JavascriptExecutor) driver).executeAsyncScript(waitForAngularJs).equals(true);
            }
};

 WebDriverWait wait = new WebDriverWait(driver, 60);
 wait.until(waitForAngular);

等待angular Javascript (为您的Java执行而修改。但我没有检查):

我将回调设置为一个简单的函数,返回true,并与根定位器[ng-app]挂钩。

代码语言:javascript
复制
var testCallback = function() {
  return true;
 };

    // Wait for angular1 testability first and run waitForAngular2 as a callback
    var waitForAngular1 = function(callback) {

      if (window.angular) {
        var hooks = window.angular.element('[ng-app]');
        if (!hooks){
          callback();  // not an angular1 app
        }
        else{
          if (hooks.$$testability) {
            hooks.$$testability.whenStable(callback);
          } else if (hooks.$injector) {
            hooks.$injector.get('$browser')
                .notifyWhenNoOutstandingRequests(callback);
          } else if (!rootSelector) {
            throw new Error(
                'Could not automatically find injector on page: "' +
                window.location.toString() + '".  Consider using config.rootEl');
          } else {
            throw new Error(
                'root element (' + rootSelector + ') has no injector.' +
                ' this may mean it is not inside ng-app.');
          }
        }
      }
      else {callback();}  // not an angular1 app
    };

    // Wait for Angular2 testability and then run test callback
    var waitForAngular2 = function() {
      if (window.getAngularTestability) {
        if (rootSelector) {
          var testability = null;
          var el = document.querySelector(rootSelector);
          try{
            testability = window.getAngularTestability(el);
          }
          catch(e){}
          if (testability) {
            testability.whenStable(testCallback);
            return;
          }
        }

        // Didn't specify root element or testability could not be found
        // by rootSelector. This may happen in a hybrid app, which could have
        // more than one root.
        var testabilities = window.getAllAngularTestabilities();
        var count = testabilities.length;

        // No angular2 testability, this happens when
        // going to a hybrid page and going back to a pure angular1 page
        if (count === 0) {
          testCallback();
          return;
        }

        var decrement = function() {
          count--;
          if (count === 0) {
            testCallback();
          }
        };
        testabilities.forEach(function(testability) {
          testability.whenStable(decrement);
        });

      }
      else {testCallback();}  // not an angular2 app
    };

    if (!(window.angular) && !(window.getAngularTestability)) {
      // no testability hook
      throw new Error(
          'both angularJS testability and angular testability are undefined.' +
          '  This could be either ' +
          'because this is a non-angular page or because your test involves ' +
          'client-side navigation, which can interfere with Protractor\'s ' +
          'bootstrapping.  See http://git.io/v4gXM for details');
    } else {waitForAngular1(waitForAngular2);}  // Wait for angular1 and angular2
// Testability hooks sequentially

为什么我们需要这个,因为angular使用了html模板,双向数据绑定,ajax请求和路由。因此,在页面导航之后,我们必须等待所有这些操作(requests & promises)完成。否则,html将不会像您所期望的那样响应。

检查角度可测试性

要基于元素进行检查,

代码语言:javascript
复制
 window.getAngularTestability(el).whenStable(callback); //Here el is element to be valiated.

要检查所有可测试性,

代码语言:javascript
复制
 window.getAllAngularTestabilities();
   testabilities.forEach(function(testability) {
        testability.whenStable(callback);
});

在检查角度可测试性之前,我们可以确保没有以下行的http请求挂起。

代码语言:javascript
复制
angular.element(document).injector().get('$http').pendingRequest.length
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52908425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档