使用量角器:使用browser.switchTo()。frame切换到iframe

时间:2016-11-14 17:19:31

标签: protractor angularjs-e2e

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

1)登录应用程序框架,然后

2)点击菜单启动我正在测试的应用程序(" MyAwesomeApp.html"此帖子)

我的主要问题是:在下面的navpanel-spec.js中,我想定位https://server/apps/Default.aspx?r=1网址,然后在运行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)

所以这里有两个网址:

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

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

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

中呈现

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

在我的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网址,然后在运行MyAwesomeApp的iframe内点击。

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

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

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

&#13;
&#13;
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);
                });
                
            });
        }
    });

});
&#13;
&#13;
&#13;

更新

&#13;
&#13;
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);
	    });

	});
    }
});

});
&#13;
&#13;
&#13;

和我的页面对象:

&#13;
&#13;
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());
    }

};
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

正如上面的评论所述,量角器有一个前缀为&#39; \ 3&#39;到你的id元素与数字。

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