{"action":"created","comment":{"url":"https://api.github.com/repos/appium/appium-base-driver/pulls/comments/222126919","pull_request_review_id":160942113,"id":222126919,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMjEyNjkxOQ==","diff_hunk":"@@ -62,6 +68,74 @@ commands.findElementsFromElement = async function (strategy, selector, elementId\n   return await this.findElOrElsWithProcessing(strategy, selector, true, elementId);\n };\n \n+/**\n+ * Find an element using a custom plugin specified by the customFindModule cap.\n+ *\n+ * @param {string} selector - the selector which the plugin will use to find\n+ * elements\n+ * @param {boolean} multiple - whether we want one element or multiple\n+ *\n+ * @returns {WebElement} - WebDriver element or list of elements\n+ */\n+commands.findByCustom = async function (selector, multiple) {\n+  if (!this.opts.customFindModule) {\n+    throw new Error(\"Finding an element using a pluagin is currently an \" +\n+                    \"incubating feature. To use it you must manually install a \" +\n+                    \"plugin module inside your Appium node_modules tree, \" +\n+                    \"and set the capability 'customFindModule' to the name of \" +\n+                    \"that module so that it can be required.\");\n+  }\n+\n+  let finder;\n+  try {\n+    finder = require(this.opts.customFindModule);","path":"lib/basedriver/commands/find.js","position":60,"original_position":60,"commit_id":"f288f2c92fd7efb22a34ba1f0cb16881f1b2295a","original_commit_id":"f288f2c92fd7efb22a34ba1f0cb16881f1b2295a","user":{"login":"jlipps","id":605053,"node_id":"MDQ6VXNlcjYwNTA1Mw==","avatar_url":"https://avatars3.githubusercontent.com/u/605053?v=4","gravatar_id":"","url":"https://api.github.com/users/jlipps","html_url":"https://github.com/jlipps","followers_url":"https://api.github.com/users/jlipps/followers","following_url":"https://api.github.com/users/jlipps/following{/other_user}","gists_url":"https://api.github.com/users/jlipps/gists{/gist_id}","starred_url":"https://api.github.com/users/jlipps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlipps/subscriptions","organizations_url":"https://api.github.com/users/jlipps/orgs","repos_url":"https://api.github.com/users/jlipps/repos","events_url":"https://api.github.com/users/jlipps/events{/privacy}","received_events_url":"https://api.github.com/users/jlipps/received_events","type":"User","site_admin":false},"body":"i'm not sure what else we can check. it's the users responsible to vet 3rd-party plugins, which could indeed be malicious.\r\n\r\nprobably at some point we'll have a registry of 'approved' plugins that we have vetted. ","created_at":"2018-10-02T22:03:06Z","updated_at":"2018-10-02T22:03:06Z","html_url":"https://github.com/appium/appium-base-driver/pull/268#discussion_r222126919","pull_request_url":"https://api.github.com/repos/appium/appium-base-driver/pulls/268","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/comments/222126919"},"html":{"href":"https://github.com/appium/appium-base-driver/pull/268#discussion_r222126919"},"pull_request":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/268"}},"in_reply_to_id":221827787},"pull_request":{"url":"https://api.github.com/repos/appium/appium-base-driver/pulls/268","id":219581344,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE5NTgxMzQ0","html_url":"https://github.com/appium/appium-base-driver/pull/268","diff_url":"https://github.com/appium/appium-base-driver/pull/268.diff","patch_url":"https://github.com/appium/appium-base-driver/pull/268.patch","issue_url":"https://api.github.com/repos/appium/appium-base-driver/issues/268","number":268,"state":"open","locked":false,"title":"add custom locator strategy","user":{"login":"jlipps","id":605053,"node_id":"MDQ6VXNlcjYwNTA1Mw==","avatar_url":"https://avatars3.githubusercontent.com/u/605053?v=4","gravatar_id":"","url":"https://api.github.com/users/jlipps","html_url":"https://github.com/jlipps","followers_url":"https://api.github.com/users/jlipps/followers","following_url":"https://api.github.com/users/jlipps/following{/other_user}","gists_url":"https://api.github.com/users/jlipps/gists{/gist_id}","starred_url":"https://api.github.com/users/jlipps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlipps/subscriptions","organizations_url":"https://api.github.com/users/jlipps/orgs","repos_url":"https://api.github.com/users/jlipps/repos","events_url":"https://api.github.com/users/jlipps/events{/privacy}","received_events_url":"https://api.github.com/users/jlipps/received_events","type":"User","site_admin":false},"body":"The idea behind this PR is to open up the possibility of \"element finding plugins\", which are third-party modules that users can use for element finding functionality that probably shouldn't be maintained by the core project but which nonetheless might be useful. (For example, I'm working on an experimental locator strategy involving a machine-learning model, which probably shouldn't become part of Appium core, at least not for some time).\r\n\r\nThe idea for how this should be used is as follows:\r\n\r\n1. A third party creates a node module that exports a `find` method matching the signature described in this PR. Essentially, that third party module is passed a driver object so it can mix and match Appium capabilities with its own logic.\r\n2. The user takes advantage of this plugin by setting the `customFindModule` capability to the name of the node module.\r\n\r\nRight now, we assume that the node module is installed in Appium's tree (or can otherwise be `require`d). In the future, with the Appium 2.0 architecture, we could allow plugins like these to be managed via the Appium CLI.\r\n\r\nWe might have other kinds of plugins in the future, beyond just element finding ones, but this is the first need I've come across.\r\n\r\nAnyway, have a look and once everyone is a fan of the idea I'll work on tests etc.","created_at":"2018-10-02T04:17:48Z","updated_at":"2018-10-02T22:03:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7a7f06c26455f7ddffcfbf193a09ac1517a5ba81","assignee":null,"assignees":[],"requested_reviewers":[{"login":"dpgraham","id":852574,"node_id":"MDQ6VXNlcjg1MjU3NA==","avatar_url":"https://avatars2.githubusercontent.com/u/852574?v=4","gravatar_id":"","url":"https://api.github.com/users/dpgraham","html_url":"https://github.com/dpgraham","followers_url":"https://api.github.com/users/dpgraham/followers","following_url":"https://api.github.com/users/dpgraham/following{/other_user}","gists_url":"https://api.github.com/users/dpgraham/gists{/gist_id}","starred_url":"https://api.github.com/users/dpgraham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dpgraham/subscriptions","organizations_url":"https://api.github.com/users/dpgraham/orgs","repos_url":"https://api.github.com/users/dpgraham/repos","events_url":"https://api.github.com/users/dpgraham/events{/privacy}","received_events_url":"https://api.github.com/users/dpgraham/received_events","type":"User","site_admin":false},{"login":"imurchie","id":2614354,"node_id":"MDQ6VXNlcjI2MTQzNTQ=","avatar_url":"https://avatars2.githubusercontent.com/u/2614354?v=4","gravatar_id":"","url":"https://api.github.com/users/imurchie","html_url":"https://github.com/imurchie","followers_url":"https://api.github.com/users/imurchie/followers","following_url":"https://api.github.com/users/imurchie/following{/other_user}","gists_url":"https://api.github.com/users/imurchie/gists{/gist_id}","starred_url":"https://api.github.com/users/imurchie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/imurchie/subscriptions","organizations_url":"https://api.github.com/users/imurchie/orgs","repos_url":"https://api.github.com/users/imurchie/repos","events_url":"https://api.github.com/users/imurchie/events{/privacy}","received_events_url":"https://api.github.com/users/imurchie/received_events","type":"User","site_admin":false},{"login":"KazuCocoa","id":5511591,"node_id":"MDQ6VXNlcjU1MTE1OTE=","avatar_url":"https://avatars3.githubusercontent.com/u/5511591?v=4","gravatar_id":"","url":"https://api.github.com/users/KazuCocoa","html_url":"https://github.com/KazuCocoa","followers_url":"https://api.github.com/users/KazuCocoa/followers","following_url":"https://api.github.com/users/KazuCocoa/following{/other_user}","gists_url":"https://api.github.com/users/KazuCocoa/gists{/gist_id}","starred_url":"https://api.github.com/users/KazuCocoa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KazuCocoa/subscriptions","organizations_url":"https://api.github.com/users/KazuCocoa/orgs","repos_url":"https://api.github.com/users/KazuCocoa/repos","events_url":"https://api.github.com/users/KazuCocoa/events{/privacy}","received_events_url":"https://api.github.com/users/KazuCocoa/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/appium/appium-base-driver/pulls/268/commits","review_comments_url":"https://api.github.com/repos/appium/appium-base-driver/pulls/268/comments","review_comment_url":"https://api.github.com/repos/appium/appium-base-driver/pulls/comments{/number}","comments_url":"https://api.github.com/repos/appium/appium-base-driver/issues/268/comments","statuses_url":"https://api.github.com/repos/appium/appium-base-driver/statuses/f288f2c92fd7efb22a34ba1f0cb16881f1b2295a","head":{"label":"appium:jlipps-custom-loc-strat","ref":"jlipps-custom-loc-strat","sha":"f288f2c92fd7efb22a34ba1f0cb16881f1b2295a","user":{"login":"appium","id":3221291,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMyMjEyOTE=","avatar_url":"https://avatars2.githubusercontent.com/u/3221291?v=4","gravatar_id":"","url":"https://api.github.com/users/appium","html_url":"https://github.com/appium","followers_url":"https://api.github.com/users/appium/followers","following_url":"https://api.github.com/users/appium/following{/other_user}","gists_url":"https://api.github.com/users/appium/gists{/gist_id}","starred_url":"https://api.github.com/users/appium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/appium/subscriptions","organizations_url":"https://api.github.com/users/appium/orgs","repos_url":"https://api.github.com/users/appium/repos","events_url":"https://api.github.com/users/appium/events{/privacy}","received_events_url":"https://api.github.com/users/appium/received_events","type":"Organization","site_admin":false},"repo":{"id":35977087,"node_id":"MDEwOlJlcG9zaXRvcnkzNTk3NzA4Nw==","name":"appium-base-driver","full_name":"appium/appium-base-driver","private":false,"owner":{"login":"appium","id":3221291,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMyMjEyOTE=","avatar_url":"https://avatars2.githubusercontent.com/u/3221291?v=4","gravatar_id":"","url":"https://api.github.com/users/appium","html_url":"https://github.com/appium","followers_url":"https://api.github.com/users/appium/followers","following_url":"https://api.github.com/users/appium/following{/other_user}","gists_url":"https://api.github.com/users/appium/gists{/gist_id}","starred_url":"https://api.github.com/users/appium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/appium/subscriptions","organizations_url":"https://api.github.com/users/appium/orgs","repos_url":"https://api.github.com/users/appium/repos","events_url":"https://api.github.com/users/appium/events{/privacy}","received_events_url":"https://api.github.com/users/appium/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/appium/appium-base-driver","description":"Base class for an Appium driver","fork":false,"url":"https://api.github.com/repos/appium/appium-base-driver","forks_url":"https://api.github.com/repos/appium/appium-base-driver/forks","keys_url":"https://api.github.com/repos/appium/appium-base-driver/keys{/key_id}","collaborators_url":"https://api.github.com/repos/appium/appium-base-driver/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/appium/appium-base-driver/teams","hooks_url":"https://api.github.com/repos/appium/appium-base-driver/hooks","issue_events_url":"https://api.github.com/repos/appium/appium-base-driver/issues/events{/number}","events_url":"https://api.github.com/repos/appium/appium-base-driver/events","assignees_url":"https://api.github.com/repos/appium/appium-base-driver/assignees{/user}","branches_url":"https://api.github.com/repos/appium/appium-base-driver/branches{/branch}","tags_url":"https://api.github.com/repos/appium/appium-base-driver/tags","blobs_url":"https://api.github.com/repos/appium/appium-base-driver/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/appium/appium-base-driver/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/appium/appium-base-driver/git/refs{/sha}","trees_url":"https://api.github.com/repos/appium/appium-base-driver/git/trees{/sha}","statuses_url":"https://api.github.com/repos/appium/appium-base-driver/statuses/{sha}","languages_url":"https://api.github.com/repos/appium/appium-base-driver/languages","stargazers_url":"https://api.github.com/repos/appium/appium-base-driver/stargazers","contributors_url":"https://api.github.com/repos/appium/appium-base-driver/contributors","subscribers_url":"https://api.github.com/repos/appium/appium-base-driver/subscribers","subscription_url":"https://api.github.com/repos/appium/appium-base-driver/subscription","commits_url":"https://api.github.com/repos/appium/appium-base-driver/commits{/sha}","git_commits_url":"https://api.github.com/repos/appium/appium-base-driver/git/commits{/sha}","comments_url":"https://api.github.com/repos/appium/appium-base-driver/comments{/number}","issue_comment_url":"https://api.github.com/repos/appium/appium-base-driver/issues/comments{/number}","contents_url":"https://api.github.com/repos/appium/appium-base-driver/contents/{+path}","compare_url":"https://api.github.com/repos/appium/appium-base-driver/compare/{base}...{head}","merges_url":"https://api.github.com/repos/appium/appium-base-driver/merges","archive_url":"https://api.github.com/repos/appium/appium-base-driver/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/appium/appium-base-driver/downloads","issues_url":"https://api.github.com/repos/appium/appium-base-driver/issues{/number}","pulls_url":"https://api.github.com/repos/appium/appium-base-driver/pulls{/number}","milestones_url":"https://api.github.com/repos/appium/appium-base-driver/milestones{/number}","notifications_url":"https://api.github.com/repos/appium/appium-base-driver/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/appium/appium-base-driver/labels{/name}","releases_url":"https://api.github.com/repos/appium/appium-base-driver/releases{/id}","deployments_url":"https://api.github.com/repos/appium/appium-base-driver/deployments","created_at":"2015-05-20T22:15:40Z","updated_at":"2018-10-02T05:33:52Z","pushed_at":"2018-10-02T05:33:50Z","git_url":"git://github.com/appium/appium-base-driver.git","ssh_url":"git@github.com:appium/appium-base-driver.git","clone_url":"https://github.com/appium/appium-base-driver.git","svn_url":"https://github.com/appium/appium-base-driver","homepage":null,"size":912,"stargazers_count":29,"watchers_count":29,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":66,"mirror_url":null,"archived":false,"open_issues_count":2,"license":{"key":"other","name":"NOASSERTION","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":66,"open_issues":2,"watchers":29,"default_branch":"master"}},"base":{"label":"appium:master","ref":"master","sha":"5cf4f1360947defb09fddbb624e1ef404a45978c","user":{"login":"appium","id":3221291,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMyMjEyOTE=","avatar_url":"https://avatars2.githubusercontent.com/u/3221291?v=4","gravatar_id":"","url":"https://api.github.com/users/appium","html_url":"https://github.com/appium","followers_url":"https://api.github.com/users/appium/followers","following_url":"https://api.github.com/users/appium/following{/other_user}","gists_url":"https://api.github.com/users/appium/gists{/gist_id}","starred_url":"https://api.github.com/users/appium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/appium/subscriptions","organizations_url":"https://api.github.com/users/appium/orgs","repos_url":"https://api.github.com/users/appium/repos","events_url":"https://api.github.com/users/appium/events{/privacy}","received_events_url":"https://api.github.com/users/appium/received_events","type":"Organization","site_admin":false},"repo":{"id":35977087,"node_id":"MDEwOlJlcG9zaXRvcnkzNTk3NzA4Nw==","name":"appium-base-driver","full_name":"appium/appium-base-driver","private":false,"owner":{"login":"appium","id":3221291,"node_id":"MDEyOk9yZ2FuaXphdGlvbjMyMjEyOTE=","avatar_url":"https://avatars2.githubusercontent.com/u/3221291?v=4","gravatar_id":"","url":"https://api.github.com/users/appium","html_url":"https://github.com/appium","followers_url":"https://api.github.com/users/appium/followers","following_url":"https://api.github.com/users/appium/following{/other_user}","gists_url":"https://api.github.com/users/appium/gists{/gist_id}","starred_url":"https://api.github.com/users/appium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/appium/subscriptions","organizations_url":"https://api.github.com/users/appium/orgs","repos_url":"https://api.github.com/users/appium/repos","events_url":"https://api.github.com/users/appium/events{/privacy}","received_events_url":"https://api.github.com/users/appium/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/appium/appium-base-driver","description":"Base class for an Appium driver","fork":false,"url":"https://api.github.com/repos/appium/appium-base-driver","forks_url":"https://api.github.com/repos/appium/appium-base-driver/forks","keys_url":"https://api.github.com/repos/appium/appium-base-driver/keys{/key_id}","collaborators_url":"https://api.github.com/repos/appium/appium-base-driver/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/appium/appium-base-driver/teams","hooks_url":"https://api.github.com/repos/appium/appium-base-driver/hooks","issue_events_url":"https://api.github.com/repos/appium/appium-base-driver/issues/events{/number}","events_url":"https://api.github.com/repos/appium/appium-base-driver/events","assignees_url":"https://api.github.com/repos/appium/appium-base-driver/assignees{/user}","branches_url":"https://api.github.com/repos/appium/appium-base-driver/branches{/branch}","tags_url":"https://api.github.com/repos/appium/appium-base-driver/tags","blobs_url":"https://api.github.com/repos/appium/appium-base-driver/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/appium/appium-base-driver/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/appium/appium-base-driver/git/refs{/sha}","trees_url":"https://api.github.com/repos/appium/appium-base-driver/git/trees{/sha}","statuses_url":"https://api.github.com/repos/appium/appium-base-driver/statuses/{sha}","languages_url":"https://api.github.com/repos/appium/appium-base-driver/languages","stargazers_url":"https://api.github.com/repos/appium/appium-base-driver/stargazers","contributors_url":"https://api.github.com/repos/appium/appium-base-driver/contributors","subscribers_url":"https://api.github.com/repos/appium/appium-base-driver/subscribers","subscription_url":"https://api.github.com/repos/appium/appium-base-driver/subscription","commits_url":"https://api.github.com/repos/appium/appium-base-driver/commits{/sha}","git_commits_url":"https://api.github.com/repos/appium/appium-base-driver/git/commits{/sha}","comments_url":"https://api.github.com/repos/appium/appium-base-driver/comments{/number}","issue_comment_url":"https://api.github.com/repos/appium/appium-base-driver/issues/comments{/number}","contents_url":"https://api.github.com/repos/appium/appium-base-driver/contents/{+path}","compare_url":"https://api.github.com/repos/appium/appium-base-driver/compare/{base}...{head}","merges_url":"https://api.github.com/repos/appium/appium-base-driver/merges","archive_url":"https://api.github.com/repos/appium/appium-base-driver/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/appium/appium-base-driver/downloads","issues_url":"https://api.github.com/repos/appium/appium-base-driver/issues{/number}","pulls_url":"https://api.github.com/repos/appium/appium-base-driver/pulls{/number}","milestones_url":"https://api.github.com/repos/appium/appium-base-driver/milestones{/number}","notifications_url":"https://api.github.com/repos/appium/appium-base-driver/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/appium/appium-base-driver/labels{/name}","releases_url":"https://api.github.com/repos/appium/appium-base-driver/releases{/id}","deployments_url":"https://api.github.com/repos/appium/appium-base-driver/deployments","created_at":"2015-05-20T22:15:40Z","updated_at":"2018-10-02T05:33:52Z","pushed_at":"2018-10-02T05:33:50Z","git_url":"git://github.com/appium/appium-base-driver.git","ssh_url":"git@github.com:appium/appium-base-driver.git","clone_url":"https://github.com/appium/appium-base-driver.git","svn_url":"https://github.com/appium/appium-base-driver","homepage":null,"size":912,"stargazers_count":29,"watchers_count":29,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":66,"mirror_url":null,"archived":false,"open_issues_count":2,"license":{"key":"other","name":"NOASSERTION","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":66,"open_issues":2,"watchers":29,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/268"},"html":{"href":"https://github.com/appium/appium-base-driver/pull/268"},"issue":{"href":"https://api.github.com/repos/appium/appium-base-driver/issues/268"},"comments":{"href":"https://api.github.com/repos/appium/appium-base-driver/issues/268/comments"},"review_comments":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/268/comments"},"review_comment":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/appium/appium-base-driver/pulls/268/commits"},"statuses":{"href":"https://api.github.com/repos/appium/appium-base-driver/statuses/f288f2c92fd7efb22a34ba1f0cb16881f1b2295a"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"jlipps"}}