最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Simple test but invalid locator :-( - Stack Overflow

programmeradmin3浏览0评论

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.

.prototype.buttonText

$ protractor --version
Version 4.0.9
$ npm -v
3.10.8
$ node -v
v6.7.0

Thanks in Advance for your ideas!

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!

Share Improve this question asked Oct 1, 2016 at 18:09 PatrickPatrick 9092 gold badges14 silver badges36 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 10

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

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

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.

发布评论

评论列表(0)

  1. 暂无评论