【问题标题】:Using Protractor: Switch to iframe using browser.switchTo().frame使用量角器:使用 browser.switchTo().frame 切换到 iframe
【发布时间】:2016-11-19 04:34:01
【问题描述】:

所以我已经编写了测试脚本:

1) 登录应用框架,然后

2) 点击菜单启动我正在测试的应用程序(本文为“MyAwesomeApp.html”)

我的主要问题是:在下面的navpanel-spec.js 中,我想定位https://server/apps/Default.aspx?r=1 URL,然后在运行 MyAwesomeApp 的 iframe 内单击。

**** 错误试图以这种方式切换到iframe,但它不起作用:

browser.switchTo().frame(element(by.id('1')).getWebElement());

Error in cmd prompt:

 Started
 [15:43:29] E/launcher - No element found using locator: By(css selector, *[id="\31 "])
 ...
 sat-navpanel-spec.js:52:24)

所以这里有两个 URL:

1) https://server/apps/Default.aspx?r=1(顶部导航中带有菜单系统的主应用程序框架)。

2) https://server/apps/MyAwesomeApp.html(测试脚本在<iframe> 标签内启动的网络应用程序。

html 看起来像这样,应用程序在 <iframe> 中呈现:

<body>
<div id="top">
    <!-- top nav menu systems rendered here -->
</div>
<div id="middle">
    <div id="m1">
        <div id="m2" class="hidden">
            <div id="m3">
                <div id="right" class="hidden">
                    <div>
                        <div id="frame_holder" style="height: 940px;">
                            <iframe style="width: 100%; height: 100%;" name="1" id="1" src="https://server/apps/MyAwesomeApp.html">
                            </iframe>
                        </div>
                    </div>
                </div>
            </div>
            <div id="left" style="display: none;"></div>
        </div>
    </div>
</div>
</body>

在我的 Protractor.config.js 文件中,我有一些规范:

specs: [     
 'spec/login.js',
 'spec/launch-awesome-app.js',
 'spec/navpanel-spec.js',        
 'spec/another-spec.js',
 'spec/yet-another-spec.js'
]

login.jslaunch-awesome-app.js 工作正常。他们登录菜单系统,然后单击菜单以启动myAwesomeapp - 没问题。

我的问题:

navpanel-spec.js 中,我想定位https://server/apps/Default.aspx?r=1 URL,然后在运行MyAwesomeApp 的iframe 中单击。

但是,它没有选择我的任何元素。

如果我在navpanel-spec.js 中定位https://server/apps/MyAwesomeApp.html,当然它会启动一个新的浏览器窗口并正常运行测试。

这是我的navpanel-spec.js 测试规范:

describe('Testing My Awesome App', function () {
    
    var panelObj = new PanelObjects();
    
    var urlDefault = 'https://server/apps/Default.aspx?r=1';
    var urlApp = 'https://server/apps/MyAwesomeApp.html';

    browser.get(urlApp);    // Runs my AwesomeApp tests okay, HOWEVER it launches a new browser window.

    browser.get(urlDefault);    // Launches app framework with top nav menus and embedded <iframe>, 
                                // HOWEVER I cannot select iframe and successfully run tests here.

    beforeEach(function () {
        browser.sleep(5000);
        browser.waitForAngular();
    });    

    // USE-CASE OBJECT !!
    var items = browser.params.useCaseJsonFile["navigatePanels"];


    browser.getAllWindowHandles().then(function (handles) {
        handles.map(function (win, idx) {
    
            browser.driver.getCurrentUrl().then(function (curr) {
                if (curr.indexOf('Default.aspx') >= 0) {
                    browser.driver.switchTo().window(handles[idx]);        
                }
            });
        });

    });

    browser.switchTo().frame(element(by.id('1')).getWebElement());
    var testId =  element(by.id('middle'));
    console.log(testId);

    items.map(function (item) {
        if (item.enableTest) {
            var specItem = it(item.name, function () {

                console.log('------------------------------');
                console.log('---- ' + item.describe);

                browser.waitForAngular();

                // select panels, etc..
                panelObj.panelClick(item.panelName).then(function () {                    
                    // ...
                });
                
                panelObj.getPanelText(item.panelName).then(function (title) {
                    expect(title).toContain(item.panelTitle);
                });
                
            });
        }
    });

});

更新

var LoginObjects = require('../pageObjects/login-objects.js');
describe('Testing My Awesome App', function () {

var panelObj = new PanelObjects();
var loginObj = new LoginObjects();

//var urlDefault = 'https://server/apps/Default.aspx?r=1';        
//browser.get(urlApp);    // Runs my AwesomeApp tests okay, HOWEVER it launches a new browser window.

browser.ignoreSynchronization = true;

// LOGIN AND LAUNCH APP !!!    
loginObj.Login();
loginObj.Launch();

beforeEach(function () {
    browser.sleep(5000);
    browser.waitForAngular();
});    

// USE-CASE OBJECT !!
var items = browser.params.useCaseJsonFile["navigatePanels"];

// SWITCH TO iframe ELEMENT
loginObj.switchWindowAndFrame();

items.map(function (item) {
    if (item.enableTest) {
	var specItem = it(item.name, function () {

	    console.log('------------------------------');
	    console.log('---- ' + item.describe);

	    browser.waitForAngular();

	    // select panels, etc..
	    panelObj.panelClick(item.panelName).then(function () {                    
		// ...
	    });

	    panelObj.getPanelText(item.panelName).then(function (title) {
		expect(title).toContain(item.panelTitle);
	    });

	});
    }
});

});

和我的页面对象:

module.exports = function(){
    this.Login = function(){

        var url = browser.params.loginUrl;        
        browser.driver.get(url);        
        browser.sleep(200);
        
        var userName = browser.params.credential.userId;
        var password = browser.params.credential.password;

        element(by.id('username')).clear().then(function(){
            element(by.id('username')).sendKeys(userName);
            element(by.id('password')).sendKeys(password);
        });
        
        browser.sleep(1000);

        var that = this;

        var submitElement = element(by.id('bthLogin')); 
        submitElement.click().then(function () {
            browser.getAllWindowHandles().then(function (handles) {
                        
                // LOGIN MESSAGE WINDOW
                browser.driver.getCurrentUrl().then(function(curr){                
                    if (curr.indexOf('LoginMsg.aspx') >= 0){
                        // Do we really need to close the login successful browser ???                    
                        browser.driver.close();
                    }
                });
                
                browser.driver.switchTo().window(handles[1]);
                
            });       
        });
        
    },

    this.Launch = function(){
        var sel = '#TheMenu1 > ul > li:first-child'; 

        var elem = element(by.css(sel));
        elem.click().then(function(){
            browser.sleep(1000);

            var elem2 = element(by.cssContainingText('.rmLink', 'The First Menu Item'));               
            elem2.click();  

            // Select menu item; sleep before attempting to click().
            var subElem = element(by.cssContainingText('.rmLink', 'My Awesome App'));
            browser.sleep(1000);
            
            subElem.click();
            browser.waitForAngular(); 
        });
    },

    this.switchWindowAndFrame = function(){

        browser.getAllWindowHandles().then(function (handles) {

            handles.map(function(win, idx){
                browser.driver.getCurrentUrl().then(function(curr){                    
                    if (curr.indexOf('Default.aspx') >= 0){                
                        browser.driver.switchTo().window(handles[idx]);                        
                    }
                });
            });

        });

        browser.switchTo().frame(element(by.css('[name="1"]')).getWebElement());
    }

};

【问题讨论】:

  • 这是我第二次看到同样的问题。您的 id 定位器以 '\3' 为前缀。这个bug还在。尝试使用其他定位器
  • 好的,我试试css定位器。谢谢。
  • 我还尝试将 nameid 值从 1 更改为其他值。在 HTML4 及更低版本中,这 2 个属性不能以数字开头。
  • @finspin - 这也是我想到的第一件事。但是当然,该应用程序已经以这种方式推出了;但是,嘿,值得一试。我总是可以要求我们更改 div ID 属性。感谢您的意见。
  • 这与 iframe 的问题没有直接关系,但您的规范文件似乎是耦合在一起的。你应该避免这种情况,因为你会遇到各种各样的问题。将登录/启动功能直接包含到您的 navpanel-spec.js 中,或者使用 PageObject 模式 stackoverflow.com/a/31624445/932210 从单独的节点包中调用它。

标签: protractor angularjs-e2e


【解决方案1】:

正如上面的 cmets 中提到的,量角器有一个错误,它会在带有数字的 id 元素前加上 '\3'。

临时方法是更改​​您的定位器。 :P

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 2021-06-19
    • 2018-12-31
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多