Simple test but invalid locator :-(
Solution 1
To extend @Gunderson's answer a little bit more. The main problem is that you are using an ElementFinder
(the result of element()
call) instead of a by
locator. See how the buttonOnward
is defined:
let buttonOnward = element(by.linkText('Continue'));
Now, you are using the buttonOnward
, which is now an ElementFinder
in place of a locator:
expect(element.all(buttonOnward).count()).toBe(1);
which, understandably, results into an "invalid locator" error.
What you meant is using the "by" locator instead:
expect(element.all(by.linkText('Continue')).count()).toBe(1);
Solution 2
I don't think your error has to do with the linkText
locator at all, your problem is with expect(element.all(buttonOnward).count()).toBe(1);
, that is an invalid locator. If you want to count the total buttons, you should just declare your locator like that:
let buttonOnward = element.all(by.linkText('Continue'));
expect(buttonOnward.count()).toBe(1);
Solution 3
In my case I was using browser.driver.findElement
. This means I was using the Selenium API. However, the Selenium API apparently doesn't support by.model
locators. However, the Protractor API does include support for the by.model
locator, and to use the Protractor API I use the element
function instead:
Doesn't 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 Protractor by.model
locator will ultimately call a CSS querySelectorAll
by prefixing with 'ng-model'
. It makes sense that Protractor adds by.model
locator functionality because Protractor is more Angular-focused.
I am assuming Selenium doesn't support by.model
natively because the "Model" locator is not listed among Selenium (Java) locators on this page
- Id
- Name
- ClassName
- CSS
- Xpath
- How to op
Nor in this Python list of Selenium methods.
Patrick
Updated on July 30, 2022Comments
-
Patrick almost 2 years
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 don't know why. Its really simple. I downloaded the typings for Jasmine and checked this file
C:\Users\Patrick\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\by.js
.There is a function defined for it:
And the documentation says 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 in Advance for your ideas!