我有这个测试:
// import {by, element, browser} from "protractor";
describe('intro', () => {
beforeEach(() => {
browser.get('');
});
it('should have multiple pages', () => {
let buttonOnward = element(by.linkText('Continue'));
expect(element.all(buttonOnward).count()).toBe(1);
});
});
得到这个结果。
1) intro should have multiple pages
Message:
Failed: Invalid locator
Stack:
TypeError: Invalid locator
at Object.check [as checkedLocator] (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js:267:9)
at WebDriver.findElements (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:919:18)
at C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\built\element.js:161:44
at ManagedPromise.invokeCallback_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27)
at C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:639:7
at process._tickCallback (internal/process/next_tick.js:103:7)
From: Task: Run it("should have multiple pages") in control flow
at Object.<anonymous> (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:79:14)
at C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:16:5
at ManagedPromise.invokeCallback_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1379:14)
at TaskQueue.execute_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2913:14)
at TaskQueue.executeNext_ (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2896:21)
at asyncRun (C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2775:27)
From asynchronous test:
Error
at Suite.describe (C:\xampp\htdocs\test\intro_spec.ts:11:3)
at Object.<anonymous> (C:\xampp\htdocs\test\intro_spec.ts:2:1)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
1 spec, 1 failure
我不知道为什么。它真的很简单。我下载了Jasmine的打字并检查了这个文件C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js
。
为它定义了一个函数:
文档说这个功能也存在。
http://www.protractortest.org/#/api?view=ProtractorBy.prototype.buttonText
$ protractor --version
Version 4.0.9
$ npm -v
3.10.8
$ node -v
v6.7.0
先感谢你的想法!
答案 0 :(得分:9)
更多地扩展@ Gunderson的答案。主要问题是您使用ElementFinder
(element()
调用的结果)而不是by
定位器。了解如何定义buttonOnward
:
let buttonOnward = element(by.linkText('Continue'));
现在,您正在使用buttonOnward
,现在是ElementFinder
代替定位器:
expect(element.all(buttonOnward).count()).toBe(1);
这可以理解地导致“无效定位器”错误。
你的意思是使用“by”定位器代替:
expect(element.all(by.linkText('Continue')).count()).toBe(1);
答案 1 :(得分:5)
我根本不认为您的错误与linkText
定位器有关,您的问题是expect(element.all(buttonOnward).count()).toBe(1);
,这是一个无效的定位器。如果你想计算总按钮数,你应该只是声明你的定位器:
let buttonOnward = element.all(by.linkText('Continue'));
expect(buttonOnward.count()).toBe(1);
答案 2 :(得分:1)
就我而言,我使用的是browser.driver.findElement
。这意味着我使用的是Selenium API。但是,Selenium API显然不支持by.model
定位器。但是,量角器 API确实包含对by.model
locator的支持,而使用量角器 API我改为使用element
函数:
不起作用:
//This would not work:
//error E/launcher - Error: TypeError: Invalid locator
browser.driver.findElement(by.model('login_form.email'))
使用:
//But this works; note it uses the `element` function
//instead of `browser.driver.findElement`
element(by.model('login_form.email'))
也有效:
//And this also works; note it uses `browser.driver.findElement`
//But it passes a different locator; not `by.model`, but `by.id`
browser.driver.findElement(by.id('#login_form_email'))
注意:
量角器by.model
定位器最终会'ng-model'
前缀by.model
。 Protractor增加by.model
定位器功能是有道理的,因为Protractor更注重角度。
我假设Selenium本身不支持(Major version).(Minor version).(Revision number).(Build number)
1.2.3 (11BCF) <- Build number, should correspond with a revision in source control
^ ^ ^
| | |
| | +--- Minor bugs, spelling mistakes, etc.
| +----- Minor features, major bug fixes, etc.
+------- Major version, UX changes, file format changes, etc.
因为“模型”定位器是call a CSS querySelectorAll
not listed among Selenium (Java) locators on this page Selenium方法列表。