Patrick Patrick - 2 months ago 38
TypeScript Question

Simple test but 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 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:

The defined function in by.js

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!

Answer

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);
Comments