2017-06-02 73 views
0

我是Angular2的新手,还没有开发出测试的Angular组件。但是,我应该编写一些UI(e2e)测试,但我甚至无法在输入字段中输入文本。Angular2 + e2e测试 - 不能使用by.id

我的问题是, element(by.id('username')).sendKeys('test') 不起作用。 (与按钮元素等相同)

我相信它只是一个小事情,但我无法找出它是什么。

我有以下配置:

  • Proctractor:5.1.2
  • 铬司机:58.0.3029.110
  • OS:Windows NT的6.1.7601 SP1 x86_64的

规格文件:

import { LoginPage } from './login.po'; 

describe('login tests', function() { 
    let page: LoginPage; 

    beforeEach(() => { 
    page = new LoginPage(); 
    }); 

    it('Demo',() => { 
    page.navigateTo(); 
    page.getUsernameInput().sendKeys('test'); 
    }); 
}); 

页面对象文件:

import { browser, element, by } from 'protractor'; 

export class LoginPage { 
    navigateTo() { 
    return browser.get('/login'); 
    } 

    getParagraphText() { 
    return element(by.class('app-root h1')).getText(); 
    } 

    getUsernameInput() { 
    return element(by.id('username')); 
    } 
} 

HTML模板:

.... 
<div> 
    <input 
    id="username" 
    name="username" 
    ngModel 
    type="text" 
    placeholder="{{something}}" 
    autocomplete="off" 
    class="input-text" 
    required> 
</div> 
... 

Proctractor配置

var SpecReporter = require('jasmine-spec-reporter'); 

exports.config = { 
    allScriptsTimeout: 120000, 
    getPageTimeout: 120000, 
    specs: [ 
     './e2e/**/*.e2e-spec.ts' 
    ], 
    capabilities: { 
     'browserName': 'chrome' 
    }, 
    directConnect: true, 
    seleniumAddress: 'http://localhost:4444/wd/hub', 
    baseUrl: 'http://localhost:8001', 
    framework: 'jasmine', 
    jasmineNodeOpts: { 
     showColors: true, 
     defaultTimeoutInterval: 30000, 
     print: function() {} 
    }, 
    useAllAngular2AppRoots: true, 
    beforeLaunch: function() { 
     require('ts-node').register({ 
     project: 'e2e' 
     }); 
    }, 
    onPrepare: function() { 
     jasmine.getEnv().addReporter(new SpecReporter()); 
    } 
}; 

任何帮助,高度赞赏。

编辑: 没有解决方案在我的情况下工作。我结束了使用browser.driver.findElement(by.id('username'));而不是element(by.id('username'));这不令人满意,因为我仍然不明白为什么这不起作用。如果有人能给我一个提示或解释,我会很感激。

+0

什么是你得到的错误?请添加您收到的错误。 – demouser123

+0

错误我的意思是文本不会被插入。但是我在控制台上看不到任何错误消息。 – Vetemi

回答

0

我相信这是由于您的getUsernameInput()方法在这种情况下不返回定位符。根据量角器文档,

element()函数返回一个ElementFinder对象。 ElementFinder知道如何使用您作为参数传入的定位器来定位DOM元素,但实际上还没有这样做。在调用操作方法之前,它不会联系浏览器。

你可以试试这个修改后的代码

getUsernameInput() { 
     element(by.id('username')).sendKeys('text'); 
    } 
    } 

,然后使用

it('Demo',() => { 
     page.navigateTo(); 
     page.getUsernameInput(); 
    }); 
}); 

而且,我不知道你的getText()会返回文本,因为getText()返回一个承诺,其你将不得不解决。这已被解释为here

+0

哦,是的,没有使用getText()。这是生成的,我忘了删除它。即使是你的改变,但不幸的是它无法工作。任何其他猜测,也许? – Vetemi

2

我认为你的问题是时机。

如果你这样做,会发生什么:

it('Demo',() => { 
    // wait for page to change to /login 
    return page.navigateTo().then(() => { 
     // then look for user input and write 'test' 
     return page.getUsernameInput().sendKeys('test'); 
    });  
}); 

编辑:

听起来很奇怪,我认为既然element(by.id('username'))browser.driver.findElement(by.id('username'))作品应该是等价的。

我使用助手类进行了很多浏览器交互,可能值得一试。

片断我用于查找元素和发送键击:

public static async getElement(locator: By | Function, waitMs?: number): Promise<ElementFinder | any> { 

    await BrowserHelper.waitForVisibilityOf(locator, waitMs | 1000); 

    return element(locator); 
} 

public static sendKeys(locator: By | Function, keys: string, clear?: boolean, waitMs?: number): Promise<void> { 
    return BrowserHelper.getElement(locator, waitMs).then((element: ElementFinder) => { 
     if (!clear) { 
      return element; 
     } 

     return element.clear().then(() => element); 
    }).then((element: ElementFinder) => { 
     return element.sendKeys(keys) 
    }); 
} 

public static async waitForVisibilityOf(locator: By | Function, waitMs?: number): Promise<any> { 
    await browser.wait(EC.presenceOf(element(locator)), waitMs || 5000).then(() => { 
     // visible 
    }, (error) => { 
     console.error('timeout at waitForVisibilityOf', locator, error); 
    }); 
} 
+0

这不是问题。它仍然不能工作。查看我的编辑了解更多信息。 – Vetemi

+0

奇怪,仍然没有输出指出'element()'版本正在发生什么?运行量角器时可能尝试添加'--verbose'标志。 – cYrixmorten