{"id":28003585,"url":"https://github.com/codef0rmer/proquery","last_synced_at":"2025-05-09T02:14:06.586Z","repository":{"id":65371321,"uuid":"45236604","full_name":"codef0rmer/proquery","owner":"codef0rmer","description":"jQuery like syntactical sugar for Protractor","archived":false,"fork":false,"pushed_at":"2016-03-13T10:16:23.000Z","size":50,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-09T02:14:02.491Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/codef0rmer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-30T07:50:26.000Z","updated_at":"2021-07-16T13:28:38.000Z","dependencies_parsed_at":"2023-01-19T22:35:15.019Z","dependency_job_id":null,"html_url":"https://github.com/codef0rmer/proquery","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codef0rmer%2Fproquery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codef0rmer%2Fproquery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codef0rmer%2Fproquery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/codef0rmer%2Fproquery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/codef0rmer","download_url":"https://codeload.github.com/codef0rmer/proquery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253176444,"owners_count":21866143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-09T02:14:06.046Z","updated_at":"2025-05-09T02:14:06.560Z","avatar_url":"https://github.com/codef0rmer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proquery\n[![Circle CI](https://img.shields.io/circleci/project/codef0rmer/proquery/master.svg)](https://circleci.com/gh/codef0rmer/proquery)\n[![npm](https://img.shields.io/npm/dm/proquery.svg)](https://www.npmjs.com/package/proquery)\n\nThe goal of this project is to help writing Integration Tests faster than ever. As everybody is pretty familiar with jQuery and it's nifty selectors for querying DOM, I decided to use jQuery approach to query elements wihout using Protractor Jargons. If you think in jQuery, you do not even have to groak Proquery API :-)\n\n## Prior Art\nhttps://github.com/angular/protractor/issues/397\n\n## Development\nResolve NPM and Bower depedencies,\n```sh\n$ npm install\n$ bower install\n```\n\n## Testing\nTo run tests against Protractor testapp:\n```sh\n$ webdriver-manager start\n$ git clone https://github.com/angular/protractor.git\n$ cd protractor/\n$ npm start\n```\n\nTo execute end-to-end tests on a specific browser, use:\n```sh\n$ git clone https://github.com/codef0rmer/proquery.git\n$ cd proquery/\n$ npm start\n$ npm test\n```\n\n## API Docs\n\nRefer tests/spec.js or tests/protractor_tests/ for more help.\n\n```sh\n$ npm install -g proquery\n\n```\n\n```js\nvar $ = require('proquery');\n```\nAs per Protractor API, `$` matches a single element, however, Proquery's `$` matches multiple elements by default. For the old behavior use:\n```sh\n$ $('.menu', true).getTagName())\n```\nThe second parameter is `useOriginal` and will match a single element instead.\n\n\n| Proquery Selectors                                        | Protractor Selectors\n| --------------------------------------------------------- | ----------------------------------------------------------------------------\n| $('iframe').length                                        | element.all(by.css('iframe')).count() \n| $('[type=\"text\"]')                                        | element.all(by.css('[type=\"text\"]')) \n| $('textarea')                                             | element.all(by.css('textarea')) \n| $('.menu')                                                | element.all(by.css('.menu')) \n| $('#checkboxes')                                          | element.all(by.id('checkboxes')) \n| $('[ng-model=\"username\"]')                                | element.all(by.model('username')) \n| $('{{username}}')                                         | element.all(by.binding('username')) \n| $('[ng-repeat=\"baz in days\"]')                            | element.all(by.repeater('baz in days')) \n| $('[ng-options=\"fruit for fruit in fruits\"]')             | element.all(by.options('fruit for fruit in fruits')) \n| $('#animals ul .pet')                                     | element.all(by.cssContainingText('#animals ul .pet')) \n| $('[type=\"text\"]:first')                                  | element.all(by.css('[type=\"text\"]')).first() \n| $('[type=\"text\"]:last')                                   | element.all(by.css('[type=\"text\"]')).last() \n| $('a:contains(\"repeater\")')                               | element.all(by.partialLinkText('repeater')) \n| $('button:contains(\"text\")')                              | element.all(by.partialButtonText('text')) \n| $('#animals ul .pet:contains(\"dog\")')                     | element.all(by.cssContainingText('#animals ul .pet', 'dog')) \n| $('[ng-model=\"fruit\"]').find('option')                    | element.all(by.model('fruit')).all(by.css('option') \n| $('[ng-model=\"fruit\"]').find('option:checked')            | element.all(by.model('fruit')).all(by.css('option:checked') \n| $(':focus')                                               | browser.driver.switchTo().activeElement() \n| $('[class=\"pet\"]').attr('value')                          | element.all(by.css('[class=\"pet\"]')).first().getAttribute('value') \n| $('[class=\"pet\"]:first').val()                            | element(by.css('[class=\"pet\"]')).getAttribute('value') \n| $('[type=\"text\"]:first').val('')                          | element(by.css('[type=\"text\"]')).clear() \n| $('[type=\"text\"]:first').val('codef0rmer')                | element(by.css('[type=\"text\"]')).sendKeys('codef0rmer') \n| $('[class=\"pet\"]:first').text()                           | element(by.css('[class=\"pet\"]')).getText() \n| $('[class=\"pet\"]:first').html()                           | element(by.css('[class=\"pet\"]')).first().getInnerHtml() \n| $('body').find('[class=\"pet\"]')                           | element.all(by.css('body')).all(by.css('[class=\"pet\"]')) \n| $('[class=\"pet\"]').get(0)                                 | element.all(by.css('[class=\"pet\"]')).get(0) \n| $('[class=\"pet\"]:eq(0)')                                  | element.all('[class=\"pet\"]').get(0).getWebElement()\n| $('[ng-repeat=\"baz in days\"]').get(0)                     | element(by.repeater('baz in days').row(0)) \n| $('[ng-repeat=\"baz in days\"]').get(0).find('baz.initial') | element(by.repeater('baz in days').row(0).column('baz.initial')) \n| $('[ng-repeat=\"baz in days\"]').find('baz.initial')        | element.all(by.repeater('baz in days').column('baz.initial')) \n| $('[ng-repeat=\"baz in days\"]').find('baz.initial').get(1) | element.all(by.repeater('baz in days').column('baz.initial').row(1)) \n| $('#checkboxes:first').is(':present')                     | element(by.id('checkboxes')).isPresent() \n| $('#checkboxes:first').is(':visible')                     | element(by.id('checkboxes')).isDisplayed() \n| $('#checkboxes:first').is(':enabled')                     | element(by.id('checkboxes')).isEnabled() \n| $('#checkboxes:first').is(':checked')                     | element(by.id('checkboxes')).isSelected() \n| $('{{greeting}}').eq(0)                                   | element.all(by.binding('greeting')).get(0).getWebElement()\n| var $doc = $('iframe').get(0).contents();\u003cbr\u003eexpect($doc.find('#checkboxes').is(':present')).toBeTruthy();\u003cbr\u003e$doc.end(); | browser.driver.switchTo().frame(0);\u003cbr\u003eexpect(element(by.id('checkboxes')).isPresent()).toBeTruthy();\u003cbr\u003ebrowser.driver.switchTo().defaultContent();\n\n## Todos\n- [ ] Support for .switchTo() popup windows\n- [ ] Support by.exactBinding and by.buttonText to map exact text instead of partial\n- [ ] Find a jQuery-like API for .switchTo().alert()\n- [ ] Support KEYS using .trigger method e.g. .trigger('enter') over .sendKeys(protractor.Key.ENTER)\n- [ ] Support complex selectors such as $('body div:last span:eq(2) a:contains(\"Link\")')\n\n## Differences with jQuery\n * .length returns promise instead of number unlike jQuery\n * .get returns matched element instead of element reference a.k.a webElement unlike jQuery\n * .eq returns element reference a.k.a webElement instead of matched element unlike jQuery\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodef0rmer%2Fproquery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodef0rmer%2Fproquery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodef0rmer%2Fproquery/lists"}