A simple test, but an invalid locator :-(
I have this test:
// 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); }); }); And get this result.
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 And I do not know why. It is very simple. I downloaded the typing for Jasmine and checked this file C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js
Function defined for it:
And the documentation says that the function exists too.
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 Thanks to Advance for your ideas!
To expand @Gunderson, answer a little more. The main problem is that you are using ElementFinder (the result of calling element() ) instead of the by locator. See how buttonOnward is buttonOnward :
let buttonOnward = element(by.linkText('Continue')); Now you use buttonOnward , which is now an ElementFinder instead of a locator:
expect(element.all(buttonOnward).count()).toBe(1); which, of course, leads to an "incorrect locator" error.
What did you mean, use the "by" locator instead:
expect(element.all(by.linkText('Continue')).count()).toBe(1); I do not think that your error is related to the linkText locator in general, your problem is related to expect(element.all(buttonOnward).count()).toBe(1); , that is, an invalid locator. If you want to count common buttons, you should simply declare your locator as follows:
let buttonOnward = element.all(by.linkText('Continue')); expect(buttonOnward.count()).toBe(1); In my case, I used browser.driver.findElement . This means that I used the Selenium API. However, the Selenium API does not seem to support by.model locators. However, the Protractor API includes support for the by.model locator and use the Protractor API Instead, I use the element function:
Does not work:
//This would not work: //error E/launcher - Error: TypeError: Invalid locator browser.driver.findElement(by.model('login_form.email')) Works:
//But this works; note it uses the `element` function //instead of `browser.driver.findElement` element(by.model('login_form.email')) Also works:
//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')) Note:
The by.model locator ultimately calls CSS querySelectorAll , the prefix is 'ng-model' . It makes sense that Protractor adds the functionality of the by.model locator, because Protractor is more Angular-focused.
I assume that Selenium does not support by.model natively because the "Model" locator is not listed among Selenium (Java) locators on this page
- Id
- Name
- Class Name
- CSS
- Xpath
- How to perform an operation
