{"action":"created","comment":{"url":"https://api.github.com/repos/davehunt/PyPOM/pulls/comments/49732774","id":49732774,"diff_hunk":"@@ -2,19 +2,63 @@\n # License, v. 2.0. If a copy of the MPL was not distributed with this\n # file, You can obtain one at http://mozilla.org/MPL/2.0/.\n \n+try:\n+    from urlparse import urljoin\n+except ImportError:\n+    from urllib.parse import urljoin\n+\n from .view import WebView\n \n \n class Page(WebView):\n \n-    _url = '{base_url}'\n+    URL_TEMPLATE = ''\n     \"\"\"String representing a URL that will return this page.\n \n     This string is formatted and can contain names of keyword arguments passed\n-    during construcion of the page object. The ``{base_url}`` keyword argument\n-    is always passed to the format operation.\n+    during construction of the page object. The template should either assume\n+    that the value of ``base_url`` will be prepended to the result of the\n+    format, or should yield an absolute URL.\n     \"\"\"\n \n+    @property\n+    def target_url(self):\n+        \"\"\"\n+        Returns the URL to the current page,\n+        formatted from :py:data:`URL_TEMPLATE`.\n+        Unless URL_TEMPLATE results in an absolute URL, ``self.base_url`` is\n+        prepended to the resulting URL.\n+\n+        :returns:\n+            String representing a URL that will return this page.\n+        \"\"\"\n+        return urljoin(self.base_url,\n+                       self.URL_TEMPLATE.format(**self.url_kwargs))","path":"pypom/page.py","position":38,"original_position":38,"commit_id":"f6d433e73e9609fb3d218937d38c5604c673b643","original_commit_id":"f6d433e73e9609fb3d218937d38c5604c673b643","user":{"login":"bobsilverberg","id":142755,"avatar_url":"https://avatars.githubusercontent.com/u/142755?v=3","gravatar_id":"","url":"https://api.github.com/users/bobsilverberg","html_url":"https://github.com/bobsilverberg","followers_url":"https://api.github.com/users/bobsilverberg/followers","following_url":"https://api.github.com/users/bobsilverberg/following{/other_user}","gists_url":"https://api.github.com/users/bobsilverberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bobsilverberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bobsilverberg/subscriptions","organizations_url":"https://api.github.com/users/bobsilverberg/orgs","repos_url":"https://api.github.com/users/bobsilverberg/repos","events_url":"https://api.github.com/users/bobsilverberg/events{/privacy}","received_events_url":"https://api.github.com/users/bobsilverberg/received_events","type":"User","site_admin":false},"body":"What I like about `urljoin` is that it has URL-smarts built in. It treats the first URL as the default for all unspecified parts of the second URL, so if the second URL is already absolute it just ignores the first URL. If the first URL is empty then it will ignore that and return the second URL unchanged. I believe it does exactly what we want, but it is causing us this coverage issue because of the two imports.\r\n\r\nI'm going to change the code to just check for the presence of `//` in the result of the format and if that is present then assume we already have an absolute URL.","created_at":"2016-01-14T14:39:34Z","updated_at":"2016-01-14T14:39:34Z","html_url":"https://github.com/davehunt/PyPOM/pull/4#discussion_r49732774","pull_request_url":"https://api.github.com/repos/davehunt/PyPOM/pulls/4","_links":{"self":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/comments/49732774"},"html":{"href":"https://github.com/davehunt/PyPOM/pull/4#discussion_r49732774"},"pull_request":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/4"}}},"pull_request":{"url":"https://api.github.com/repos/davehunt/PyPOM/pulls/4","id":55955022,"html_url":"https://github.com/davehunt/PyPOM/pull/4","diff_url":"https://github.com/davehunt/PyPOM/pull/4.diff","patch_url":"https://github.com/davehunt/PyPOM/pull/4.patch","issue_url":"https://api.github.com/repos/davehunt/PyPOM/issues/4","number":4,"state":"open","locked":false,"title":"Address suggestions from the meeting of Jan 13","user":{"login":"bobsilverberg","id":142755,"avatar_url":"https://avatars.githubusercontent.com/u/142755?v=3","gravatar_id":"","url":"https://api.github.com/users/bobsilverberg","html_url":"https://github.com/bobsilverberg","followers_url":"https://api.github.com/users/bobsilverberg/followers","following_url":"https://api.github.com/users/bobsilverberg/following{/other_user}","gists_url":"https://api.github.com/users/bobsilverberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bobsilverberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bobsilverberg/subscriptions","organizations_url":"https://api.github.com/users/bobsilverberg/orgs","repos_url":"https://api.github.com/users/bobsilverberg/repos","events_url":"https://api.github.com/users/bobsilverberg/events{/privacy}","received_events_url":"https://api.github.com/users/bobsilverberg/received_events","type":"User","site_admin":false},"body":"Make base_url optional, and reorder arguments to place selenium first\r\nRename _url to URL_TEMPLATE\r\nRename url to target_url\r\nPrepend base_url to the result of URL_TEMPLATE if it does not result in an absolute URL\r\nRename kwargs to url_kwargs\r\nRemove timeout property and replace with an argument to WebView.__init__\r\nMove find_element* methods into Page and Region\r\nIn wait_for_page_to_load, only perform the URL check if target_url yields a value\r\nAdd/change tests for new/changed functionality","created_at":"2016-01-13T21:02:13Z","updated_at":"2016-01-14T14:39:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a58f35d89e2f607989ac0f04a040f7f986e4833a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/davehunt/PyPOM/pulls/4/commits","review_comments_url":"https://api.github.com/repos/davehunt/PyPOM/pulls/4/comments","review_comment_url":"https://api.github.com/repos/davehunt/PyPOM/pulls/comments{/number}","comments_url":"https://api.github.com/repos/davehunt/PyPOM/issues/4/comments","statuses_url":"https://api.github.com/repos/davehunt/PyPOM/statuses/f6d433e73e9609fb3d218937d38c5604c673b643","head":{"label":"bobsilverberg:updates","ref":"updates","sha":"f6d433e73e9609fb3d218937d38c5604c673b643","user":{"login":"bobsilverberg","id":142755,"avatar_url":"https://avatars.githubusercontent.com/u/142755?v=3","gravatar_id":"","url":"https://api.github.com/users/bobsilverberg","html_url":"https://github.com/bobsilverberg","followers_url":"https://api.github.com/users/bobsilverberg/followers","following_url":"https://api.github.com/users/bobsilverberg/following{/other_user}","gists_url":"https://api.github.com/users/bobsilverberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bobsilverberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bobsilverberg/subscriptions","organizations_url":"https://api.github.com/users/bobsilverberg/orgs","repos_url":"https://api.github.com/users/bobsilverberg/repos","events_url":"https://api.github.com/users/bobsilverberg/events{/privacy}","received_events_url":"https://api.github.com/users/bobsilverberg/received_events","type":"User","site_admin":false},"repo":{"id":47768888,"name":"PyPOM","full_name":"bobsilverberg/PyPOM","owner":{"login":"bobsilverberg","id":142755,"avatar_url":"https://avatars.githubusercontent.com/u/142755?v=3","gravatar_id":"","url":"https://api.github.com/users/bobsilverberg","html_url":"https://github.com/bobsilverberg","followers_url":"https://api.github.com/users/bobsilverberg/followers","following_url":"https://api.github.com/users/bobsilverberg/following{/other_user}","gists_url":"https://api.github.com/users/bobsilverberg/gists{/gist_id}","starred_url":"https://api.github.com/users/bobsilverberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bobsilverberg/subscriptions","organizations_url":"https://api.github.com/users/bobsilverberg/orgs","repos_url":"https://api.github.com/users/bobsilverberg/repos","events_url":"https://api.github.com/users/bobsilverberg/events{/privacy}","received_events_url":"https://api.github.com/users/bobsilverberg/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bobsilverberg/PyPOM","description":"Python page object model for Selenium","fork":true,"url":"https://api.github.com/repos/bobsilverberg/PyPOM","forks_url":"https://api.github.com/repos/bobsilverberg/PyPOM/forks","keys_url":"https://api.github.com/repos/bobsilverberg/PyPOM/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bobsilverberg/PyPOM/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bobsilverberg/PyPOM/teams","hooks_url":"https://api.github.com/repos/bobsilverberg/PyPOM/hooks","issue_events_url":"https://api.github.com/repos/bobsilverberg/PyPOM/issues/events{/number}","events_url":"https://api.github.com/repos/bobsilverberg/PyPOM/events","assignees_url":"https://api.github.com/repos/bobsilverberg/PyPOM/assignees{/user}","branches_url":"https://api.github.com/repos/bobsilverberg/PyPOM/branches{/branch}","tags_url":"https://api.github.com/repos/bobsilverberg/PyPOM/tags","blobs_url":"https://api.github.com/repos/bobsilverberg/PyPOM/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bobsilverberg/PyPOM/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bobsilverberg/PyPOM/git/refs{/sha}","trees_url":"https://api.github.com/repos/bobsilverberg/PyPOM/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bobsilverberg/PyPOM/statuses/{sha}","languages_url":"https://api.github.com/repos/bobsilverberg/PyPOM/languages","stargazers_url":"https://api.github.com/repos/bobsilverberg/PyPOM/stargazers","contributors_url":"https://api.github.com/repos/bobsilverberg/PyPOM/contributors","subscribers_url":"https://api.github.com/repos/bobsilverberg/PyPOM/subscribers","subscription_url":"https://api.github.com/repos/bobsilverberg/PyPOM/subscription","commits_url":"https://api.github.com/repos/bobsilverberg/PyPOM/commits{/sha}","git_commits_url":"https://api.github.com/repos/bobsilverberg/PyPOM/git/commits{/sha}","comments_url":"https://api.github.com/repos/bobsilverberg/PyPOM/comments{/number}","issue_comment_url":"https://api.github.com/repos/bobsilverberg/PyPOM/issues/comments{/number}","contents_url":"https://api.github.com/repos/bobsilverberg/PyPOM/contents/{+path}","compare_url":"https://api.github.com/repos/bobsilverberg/PyPOM/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bobsilverberg/PyPOM/merges","archive_url":"https://api.github.com/repos/bobsilverberg/PyPOM/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bobsilverberg/PyPOM/downloads","issues_url":"https://api.github.com/repos/bobsilverberg/PyPOM/issues{/number}","pulls_url":"https://api.github.com/repos/bobsilverberg/PyPOM/pulls{/number}","milestones_url":"https://api.github.com/repos/bobsilverberg/PyPOM/milestones{/number}","notifications_url":"https://api.github.com/repos/bobsilverberg/PyPOM/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bobsilverberg/PyPOM/labels{/name}","releases_url":"https://api.github.com/repos/bobsilverberg/PyPOM/releases{/id}","created_at":"2015-12-10T15:02:20Z","updated_at":"2015-12-10T15:02:21Z","pushed_at":"2016-01-14T13:16:31Z","git_url":"git://github.com/bobsilverberg/PyPOM.git","ssh_url":"git@github.com:bobsilverberg/PyPOM.git","clone_url":"https://github.com/bobsilverberg/PyPOM.git","svn_url":"https://github.com/bobsilverberg/PyPOM","homepage":null,"size":31,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"davehunt:master","ref":"master","sha":"af4af244edf6ab96e23206847052cdcfe126bb09","user":{"login":"davehunt","id":122800,"avatar_url":"https://avatars.githubusercontent.com/u/122800?v=3","gravatar_id":"","url":"https://api.github.com/users/davehunt","html_url":"https://github.com/davehunt","followers_url":"https://api.github.com/users/davehunt/followers","following_url":"https://api.github.com/users/davehunt/following{/other_user}","gists_url":"https://api.github.com/users/davehunt/gists{/gist_id}","starred_url":"https://api.github.com/users/davehunt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davehunt/subscriptions","organizations_url":"https://api.github.com/users/davehunt/orgs","repos_url":"https://api.github.com/users/davehunt/repos","events_url":"https://api.github.com/users/davehunt/events{/privacy}","received_events_url":"https://api.github.com/users/davehunt/received_events","type":"User","site_admin":false},"repo":{"id":47700964,"name":"PyPOM","full_name":"davehunt/PyPOM","owner":{"login":"davehunt","id":122800,"avatar_url":"https://avatars.githubusercontent.com/u/122800?v=3","gravatar_id":"","url":"https://api.github.com/users/davehunt","html_url":"https://github.com/davehunt","followers_url":"https://api.github.com/users/davehunt/followers","following_url":"https://api.github.com/users/davehunt/following{/other_user}","gists_url":"https://api.github.com/users/davehunt/gists{/gist_id}","starred_url":"https://api.github.com/users/davehunt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davehunt/subscriptions","organizations_url":"https://api.github.com/users/davehunt/orgs","repos_url":"https://api.github.com/users/davehunt/repos","events_url":"https://api.github.com/users/davehunt/events{/privacy}","received_events_url":"https://api.github.com/users/davehunt/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/davehunt/PyPOM","description":"Python page object model for Selenium","fork":false,"url":"https://api.github.com/repos/davehunt/PyPOM","forks_url":"https://api.github.com/repos/davehunt/PyPOM/forks","keys_url":"https://api.github.com/repos/davehunt/PyPOM/keys{/key_id}","collaborators_url":"https://api.github.com/repos/davehunt/PyPOM/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/davehunt/PyPOM/teams","hooks_url":"https://api.github.com/repos/davehunt/PyPOM/hooks","issue_events_url":"https://api.github.com/repos/davehunt/PyPOM/issues/events{/number}","events_url":"https://api.github.com/repos/davehunt/PyPOM/events","assignees_url":"https://api.github.com/repos/davehunt/PyPOM/assignees{/user}","branches_url":"https://api.github.com/repos/davehunt/PyPOM/branches{/branch}","tags_url":"https://api.github.com/repos/davehunt/PyPOM/tags","blobs_url":"https://api.github.com/repos/davehunt/PyPOM/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/davehunt/PyPOM/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/davehunt/PyPOM/git/refs{/sha}","trees_url":"https://api.github.com/repos/davehunt/PyPOM/git/trees{/sha}","statuses_url":"https://api.github.com/repos/davehunt/PyPOM/statuses/{sha}","languages_url":"https://api.github.com/repos/davehunt/PyPOM/languages","stargazers_url":"https://api.github.com/repos/davehunt/PyPOM/stargazers","contributors_url":"https://api.github.com/repos/davehunt/PyPOM/contributors","subscribers_url":"https://api.github.com/repos/davehunt/PyPOM/subscribers","subscription_url":"https://api.github.com/repos/davehunt/PyPOM/subscription","commits_url":"https://api.github.com/repos/davehunt/PyPOM/commits{/sha}","git_commits_url":"https://api.github.com/repos/davehunt/PyPOM/git/commits{/sha}","comments_url":"https://api.github.com/repos/davehunt/PyPOM/comments{/number}","issue_comment_url":"https://api.github.com/repos/davehunt/PyPOM/issues/comments{/number}","contents_url":"https://api.github.com/repos/davehunt/PyPOM/contents/{+path}","compare_url":"https://api.github.com/repos/davehunt/PyPOM/compare/{base}...{head}","merges_url":"https://api.github.com/repos/davehunt/PyPOM/merges","archive_url":"https://api.github.com/repos/davehunt/PyPOM/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/davehunt/PyPOM/downloads","issues_url":"https://api.github.com/repos/davehunt/PyPOM/issues{/number}","pulls_url":"https://api.github.com/repos/davehunt/PyPOM/pulls{/number}","milestones_url":"https://api.github.com/repos/davehunt/PyPOM/milestones{/number}","notifications_url":"https://api.github.com/repos/davehunt/PyPOM/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/davehunt/PyPOM/labels{/name}","releases_url":"https://api.github.com/repos/davehunt/PyPOM/releases{/id}","created_at":"2015-12-09T15:44:26Z","updated_at":"2016-01-11T12:47:34Z","pushed_at":"2016-01-13T21:08:34Z","git_url":"git://github.com/davehunt/PyPOM.git","ssh_url":"git@github.com:davehunt/PyPOM.git","clone_url":"https://github.com/davehunt/PyPOM.git","svn_url":"https://github.com/davehunt/PyPOM","homepage":null,"size":25,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/4"},"html":{"href":"https://github.com/davehunt/PyPOM/pull/4"},"issue":{"href":"https://api.github.com/repos/davehunt/PyPOM/issues/4"},"comments":{"href":"https://api.github.com/repos/davehunt/PyPOM/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/davehunt/PyPOM/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/davehunt/PyPOM/statuses/f6d433e73e9609fb3d218937d38c5604c673b643"}}}}