Merge branch 'develop' into fix/metamask-address-not-updated-#187
This commit is contained in:
commit
c3798e98d9
|
@ -69,7 +69,6 @@
|
||||||
[lein-auto "0.1.2"]
|
[lein-auto "0.1.2"]
|
||||||
[lein-less "1.7.5"]
|
[lein-less "1.7.5"]
|
||||||
[lein-shell "0.5.0"]
|
[lein-shell "0.5.0"]
|
||||||
[cider/cider-nrepl "0.15.0-SNAPSHOT"]
|
|
||||||
[lein-sha-version "0.1.1"]]
|
[lein-sha-version "0.1.1"]]
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 327 KiB |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 322 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,7 +1,7 @@
|
||||||
(ns commiteth.core
|
(ns commiteth.core
|
||||||
(:require [commiteth.handler :as handler]
|
(:require [commiteth.handler :as handler]
|
||||||
[clojure.tools.nrepl.server :as nrepl-server]
|
[clojure.tools.nrepl.server :as nrepl-server]
|
||||||
[cider.nrepl :refer [cider-nrepl-handler]]
|
[luminus.repl-server :as repl]
|
||||||
[luminus.http-server :as http]
|
[luminus.http-server :as http]
|
||||||
[luminus-migrations.core :as migrations]
|
[luminus-migrations.core :as migrations]
|
||||||
[commiteth.config :refer [env]]
|
[commiteth.config :refer [env]]
|
||||||
|
@ -31,7 +31,7 @@ repl-server
|
||||||
(when-let [nrepl-port (env :nrepl-port)]
|
(when-let [nrepl-port (env :nrepl-port)]
|
||||||
(log/info "Starting NREPL server on port" nrepl-port)
|
(log/info "Starting NREPL server on port" nrepl-port)
|
||||||
(nrepl-server/start-server :port nrepl-port
|
(nrepl-server/start-server :port nrepl-port
|
||||||
:handler cider-nrepl-handler))
|
:handler nrepl-server/default-handler))
|
||||||
:stop
|
:stop
|
||||||
(when repl-server
|
(when repl-server
|
||||||
(nrepl-server/stop-server repl-server)))
|
(nrepl-server/stop-server repl-server)))
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
[commiteth.handlers :as handlers]
|
[commiteth.handlers :as handlers]
|
||||||
[commiteth.db :as db]
|
[commiteth.db :as db]
|
||||||
[commiteth.ui-model :as ui-model]
|
[commiteth.ui-model :as ui-model]
|
||||||
[commiteth.subscriptions :as subs]))
|
[commiteth.subscriptions :as subs]
|
||||||
|
[commiteth.util :as util]))
|
||||||
|
|
||||||
|
|
||||||
(defn bounty-item [bounty]
|
(defn bounty-item [bounty]
|
||||||
|
@ -207,8 +208,11 @@
|
||||||
[:div
|
[:div
|
||||||
(let [left (inc (* (dec page-number) items-per-page))
|
(let [left (inc (* (dec page-number) items-per-page))
|
||||||
right (dec (+ left item-count))]
|
right (dec (+ left item-count))]
|
||||||
[:div.item-counts-label
|
[:div.item-counts-label-and-sorting-container
|
||||||
[:span (str "Showing " left "-" right " of " total-count)]])
|
[:div.item-counts-label
|
||||||
|
[:span (str "Showing " left "-" right " of " total-count)]]
|
||||||
|
(when-not (util/os-windows?)
|
||||||
|
[bounties-sort-view])])
|
||||||
(display-data-page bounty-page-data bounty-item container-element)]))
|
(display-data-page bounty-page-data bounty-item container-element)]))
|
||||||
|
|
||||||
(defn bounties-page []
|
(defn bounties-page []
|
||||||
|
@ -223,8 +227,7 @@
|
||||||
[:div.ui.container.open-bounties-container
|
[:div.ui.container.open-bounties-container
|
||||||
{:ref #(reset! container-element %1)}
|
{:ref #(reset! container-element %1)}
|
||||||
[:div.open-bounties-header "Bounties"]
|
[:div.open-bounties-header "Bounties"]
|
||||||
[:div.open-bounties-filter-and-sort
|
(when-not (util/os-windows?)
|
||||||
[bounty-filters-view]
|
[:div.open-bounties-filter-and-sort
|
||||||
[bounties-sort-view]]
|
[bounty-filters-view]])
|
||||||
[bounties-list @bounty-page-data container-element]]))
|
[bounties-list @bounty-page-data container-element]]))))
|
||||||
))
|
|
||||||
|
|
|
@ -208,12 +208,12 @@
|
||||||
[:div.ui.vertical.segment
|
[:div.ui.vertical.segment
|
||||||
[:div.ui.container
|
[:div.ui.container
|
||||||
[:div.ui.grid.stackable
|
[:div.ui.grid.stackable
|
||||||
[:div {:class (str (if (show-top-hunters?) "ten" "sixteen")
|
[:div {:class (str (if (show-top-hunters?) "eleven" "sixteen")
|
||||||
" wide computer sixteen wide tablet column")}
|
" wide computer sixteen wide tablet column")}
|
||||||
[:div.ui.container
|
[:div.ui.container
|
||||||
[(pages @current-page)]]]
|
[(pages @current-page)]]]
|
||||||
(when (show-top-hunters?)
|
(when (show-top-hunters?)
|
||||||
[:div.six.wide.column.computer.only
|
[:div.five.wide.column.computer.only
|
||||||
[:div.ui.container.top-hunters
|
[:div.ui.container.top-hunters
|
||||||
[:h3.top-hunters-header "Top 5 hunters"]
|
[:h3.top-hunters-header "Top 5 hunters"]
|
||||||
[:div.top-hunters-subheader "All time"]
|
[:div.top-hunters-subheader "All time"]
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
(ns commiteth.util
|
||||||
|
(:require [clojure.string :as string]))
|
||||||
|
|
||||||
|
(defn os-windows? []
|
||||||
|
(string/includes? (-> js/navigator .-platform) "Win"))
|
|
@ -414,6 +414,11 @@
|
||||||
color: #42505c;
|
color: #42505c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-counts-label-and-sorting-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.open-bounties-filter-and-sort {
|
.open-bounties-filter-and-sort {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -442,6 +447,7 @@
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
margin: 8px 12px;
|
margin: 8px 12px;
|
||||||
|
@ -508,7 +514,10 @@
|
||||||
margin: 14.5px 0;
|
margin: 14.5px 0;
|
||||||
}
|
}
|
||||||
input[type=range]:focus {
|
input[type=range]:focus {
|
||||||
outline: none;
|
outline: 0;
|
||||||
|
}
|
||||||
|
input[type=range]::-moz-focus-outer {
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
input[type=range]::-webkit-slider-runnable-track {
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -635,11 +644,6 @@
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
|
||||||
background: green;
|
|
||||||
transform: scale(1.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:hover {
|
input:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -671,7 +675,7 @@
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
line-height: 1.0;
|
line-height: 1.0;
|
||||||
color: #8d99a4;
|
color: #8d99a4;
|
||||||
padding: 8px 12px;
|
padding: 16px 12px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
@ -713,6 +717,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.open-bounty-item:first-child {
|
||||||
|
border-top: #eaecee 1px solid !important;
|
||||||
|
}
|
||||||
|
|
||||||
.open-bounty-item {
|
.open-bounty-item {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -1269,12 +1277,11 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-counts-label {
|
.item-counts-label {
|
||||||
margin: auto;
|
//margin: auto;
|
||||||
font-family: "PostGrotesk-Book";
|
font-family: "PostGrotesk-Book";
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: #8d99a4;
|
color: #8d99a4;
|
||||||
padding-top: 8px;
|
padding-top: 20px;
|
||||||
padding-bottom: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,3 +15,4 @@ class BasePageObject(object):
|
||||||
@property
|
@property
|
||||||
def time_now(self):
|
def time_now(self):
|
||||||
return datetime.now().strftime('%-m%-d%-H%-M%-S')
|
return datetime.now().strftime('%-m%-d%-H%-M%-S')
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ import time, pytest
|
||||||
from pages.base_element import *
|
from pages.base_element import *
|
||||||
from pages.base_page import BasePageObject
|
from pages.base_page import BasePageObject
|
||||||
from tests import test_data
|
from tests import test_data
|
||||||
|
from git import Repo
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class EmailEditbox(BaseEditBox):
|
class EmailEditbox(BaseEditBox):
|
||||||
|
@ -106,7 +110,46 @@ class ContractBody(BaseText):
|
||||||
super(ContractBody, self).__init__(driver)
|
super(ContractBody, self).__init__(driver)
|
||||||
self.locator = self.Locator.xpath_selector("//tbody//p[contains(text(), "
|
self.locator = self.Locator.xpath_selector("//tbody//p[contains(text(), "
|
||||||
"'Current balance: 0.000000 ETH')]")
|
"'Current balance: 0.000000 ETH')]")
|
||||||
|
class IssueId(BaseText):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(IssueId, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector(".gh-header-number")
|
||||||
|
|
||||||
|
class ForkButton(BaseButton):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(ForkButton, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector("[href='#fork-destination-box']")
|
||||||
|
|
||||||
|
class HeaderInForkPopup(BaseText):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(HeaderInForkPopup, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector("#facebox-header")
|
||||||
|
|
||||||
|
class UserAccountInForkPopup(BaseButton):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(UserAccountInForkPopup, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector("[value=%s]"%test_data.config['DEV']['gh_username'])
|
||||||
|
|
||||||
|
|
||||||
|
class ForkedRepoText(BaseText):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(ForkedRepoText, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector(".commit-tease")
|
||||||
|
|
||||||
|
class DeleteRepo(BaseButton):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(DeleteRepo, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.xpath_selector("//button[text()[contains(.,' Delete this repository')]]")
|
||||||
|
|
||||||
|
class RepoNameBoxInPopup(BaseEditBox):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(RepoNameBoxInPopup, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.css_selector("input[aria-label='Type in the name of the repository to confirm that you want to delete this repository.']")
|
||||||
|
|
||||||
|
class ConfirmDeleteButton(BaseButton):
|
||||||
|
def __init__(self, driver):
|
||||||
|
super(ConfirmDeleteButton, self).__init__(driver)
|
||||||
|
self.locator = self.Locator.xpath_selector("//button[text()[contains(.,'I understand the consequences, delete')]]")
|
||||||
|
|
||||||
class GithubPage(BasePageObject):
|
class GithubPage(BasePageObject):
|
||||||
def __init__(self, driver):
|
def __init__(self, driver):
|
||||||
|
@ -133,18 +176,32 @@ class GithubPage(BasePageObject):
|
||||||
self.cross_button = LabelsButton.CrossButton(self.driver)
|
self.cross_button = LabelsButton.CrossButton(self.driver)
|
||||||
self.submit_new_issue_button = SubmitNewIssueButton(self.driver)
|
self.submit_new_issue_button = SubmitNewIssueButton(self.driver)
|
||||||
self.contract_body = ContractBody(self.driver)
|
self.contract_body = ContractBody(self.driver)
|
||||||
|
self.issue_id = IssueId(self.driver)
|
||||||
|
self.fork_button = ForkButton(self.driver)
|
||||||
|
self.header_in_fork_popup = HeaderInForkPopup(self.driver)
|
||||||
|
self.user_account_in_fork_popup = UserAccountInForkPopup(self.driver)
|
||||||
|
self.forked_repo_text = ForkedRepoText(self.driver)
|
||||||
|
|
||||||
|
self.delete_repo = DeleteRepo(self.driver)
|
||||||
|
self.repo_name_confirm_delete = RepoNameBoxInPopup(self.driver)
|
||||||
|
self.confirm_delete = ConfirmDeleteButton(self.driver)
|
||||||
|
|
||||||
|
|
||||||
def get_issues_page(self):
|
def get_issues_page(self):
|
||||||
self.driver.get('https://github.com/Org4/nov13/issues')
|
self.driver.get(test_data.config['ORG']['gh_repo'] + 'issues')
|
||||||
|
|
||||||
|
def get_issue_page(self, issue_id):
|
||||||
|
self.driver.get(test_data.config['ORG']['gh_repo'] + 'issues/' + issue_id)
|
||||||
|
|
||||||
def get_sob_plugin_page(self):
|
def get_sob_plugin_page(self):
|
||||||
self.driver.get('http://github.com/apps/status-open-bounty-app-test')
|
self.driver.get(test_data.config['Common']['sob_test_app'])
|
||||||
|
|
||||||
def sign_in(self, email, password):
|
def sign_in(self, email, password):
|
||||||
self.email_input.send_keys(email)
|
self.email_input.send_keys(email)
|
||||||
self.password_input.send_keys(password)
|
self.password_input.send_keys(password)
|
||||||
self.sign_in_button.click()
|
self.sign_in_button.click()
|
||||||
|
|
||||||
|
|
||||||
def install_sob_plugin(self):
|
def install_sob_plugin(self):
|
||||||
initial_url = self.driver.current_url
|
initial_url = self.driver.current_url
|
||||||
self.get_sob_plugin_page()
|
self.get_sob_plugin_page()
|
||||||
|
@ -164,7 +221,18 @@ class GithubPage(BasePageObject):
|
||||||
self.bounty_label.click()
|
self.bounty_label.click()
|
||||||
self.cross_button.click()
|
self.cross_button.click()
|
||||||
self.submit_new_issue_button.click()
|
self.submit_new_issue_button.click()
|
||||||
return test_data.issue['title']
|
test_data.issue['id'] = self.issue_id.text[1:]
|
||||||
|
logging.info("Issue title is %s" % test_data.issue['title'])
|
||||||
|
|
||||||
|
def fork_repo(self, initial_repo, wait=60):
|
||||||
|
self.driver.get(initial_repo)
|
||||||
|
self.fork_button.click()
|
||||||
|
if self.header_in_fork_popup.text == 'Where should we fork this repository?':
|
||||||
|
self.user_account_in_fork_popup.click()
|
||||||
|
self.forked_repo_text.wait_for_element(wait)
|
||||||
|
|
||||||
|
def get_login_page(self):
|
||||||
|
self.driver.get(test_data.config['Common']['gh_login'])
|
||||||
|
|
||||||
def get_deployed_contract(self, wait=120):
|
def get_deployed_contract(self, wait=120):
|
||||||
for i in range(wait):
|
for i in range(wait):
|
||||||
|
@ -175,3 +243,34 @@ class GithubPage(BasePageObject):
|
||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
pass
|
pass
|
||||||
pytest.fail('Contract is not deployed in %s minutes!' % str(wait/60))
|
pytest.fail('Contract is not deployed in %s minutes!' % str(wait/60))
|
||||||
|
|
||||||
|
#cloning via HTTPS
|
||||||
|
def clone_repo(self, initial_repo=None, username=None, repo_name=None, repo_path='git_repo'):
|
||||||
|
os.mkdir(repo_path)
|
||||||
|
os.chdir(repo_path)
|
||||||
|
test_data.local_repo_path = os.getcwd()
|
||||||
|
fork = 'https://github.com/%s/%s.git' % (username, repo_name)
|
||||||
|
logging.info(('Cloning from %s to %s' % (fork, repo_path)))
|
||||||
|
r = Repo.clone_from(fork, repo_path)
|
||||||
|
logging.info(('Successefully cloned to: %s' % test_data.local_repo_path))
|
||||||
|
logging.info('Set upstream to %s'% initial_repo)
|
||||||
|
upstream = r.create_remote('upstream', initial_repo)
|
||||||
|
upstream.fetch()
|
||||||
|
assert upstream.exists()
|
||||||
|
r.heads.master.checkout()
|
||||||
|
|
||||||
|
def clean_repo_local_folder(self):
|
||||||
|
logging.info('Removing %s' % test_data.local_repo_path)
|
||||||
|
if test_data.local_repo_path:
|
||||||
|
shutil.rmtree(test_data.local_repo_path)
|
||||||
|
|
||||||
|
def delete_fork(self):
|
||||||
|
self.get_url(test_data.config['DEV']['gh_forked_repo'] + 'settings')
|
||||||
|
self.delete_repo.click()
|
||||||
|
self.repo_name_confirm_delete.send_keys(test_data.config['ORG']['gh_repo_name'])
|
||||||
|
self.confirm_delete.click()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,3 +16,6 @@ selenium==2.53.6
|
||||||
six==1.10.0
|
six==1.10.0
|
||||||
urllib3==1.22
|
urllib3==1.22
|
||||||
yarl==0.12.0
|
yarl==0.12.0
|
||||||
|
gitpython==2.1.8
|
||||||
|
gitdb2==2.0.3
|
||||||
|
smmap2==2.0.3
|
|
@ -7,11 +7,14 @@ class TestData(object):
|
||||||
self.config = configparser.ConfigParser()
|
self.config = configparser.ConfigParser()
|
||||||
|
|
||||||
# define here path to your config.ini file
|
# define here path to your config.ini file
|
||||||
#example - config_example.ini
|
# example - config_example.ini
|
||||||
|
|
||||||
self.config.read('config.ini')
|
self.config.read('config.ini')
|
||||||
self.base_case_issue = dict()
|
|
||||||
self.base_case_issue['title'] = 'Very first auto_test_bounty'
|
# self.issue['title'] is set in GithubPage::create_new_bounty
|
||||||
|
# self.issue['id'] is set in GithubPage::create_new_bounty
|
||||||
|
# self.local_repo_path is set in GithubPage::clone_repo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
test_data = TestData()
|
test_data = TestData()
|
||||||
|
|
|
@ -4,63 +4,25 @@ from selenium.common.exceptions import WebDriverException
|
||||||
from tests.postconditions import remove_application, remove_installation
|
from tests.postconditions import remove_application, remove_installation
|
||||||
from os import environ, path
|
from os import environ, path
|
||||||
from tests import test_data
|
from tests import test_data
|
||||||
|
from pages.thirdparty.github import GithubPage
|
||||||
|
from pages.openbounty.landing import LandingPage
|
||||||
|
|
||||||
class BaseTestCase:
|
class BaseTestCase:
|
||||||
|
|
||||||
@property
|
|
||||||
def sauce_username(self):
|
|
||||||
return environ.get('SAUCE_USERNAME')
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def sauce_access_key(self):
|
|
||||||
return environ.get('SAUCE_ACCESS_KEY')
|
|
||||||
|
|
||||||
|
|
||||||
@property
|
|
||||||
def executor_sauce_lab(self):
|
|
||||||
return 'http://%s:%s@ondemand.saucelabs.com:80/wd/hub' % (self.sauce_username, self.sauce_access_key)
|
|
||||||
|
|
||||||
def print_sauce_lab_info(self, driver):
|
def print_sauce_lab_info(self, driver):
|
||||||
sys.stdout = sys.stderr
|
sys.stdout = sys.stderr
|
||||||
print("SauceOnDemandSessionID=%s job-name=%s" % (driver.session_id,
|
print("SauceOnDemandSessionID=%s job-name=%s" % (driver.session_id,
|
||||||
pytest.config.getoption('build')))
|
pytest.config.getoption('build')))
|
||||||
|
def get_remote_caps(self):
|
||||||
@property
|
sauce_lab_cap = dict()
|
||||||
def capabilities_sauce_lab(self):
|
sauce_lab_cap['name'] = test_data.test_name
|
||||||
|
sauce_lab_cap['build'] = pytest.config.getoption('build')
|
||||||
desired_caps = dict()
|
sauce_lab_cap['platform'] = "MAC"
|
||||||
desired_caps['name'] = test_data.test_name
|
sauce_lab_cap['browserName'] = 'Chrome'
|
||||||
desired_caps['build'] = pytest.config.getoption('build')
|
sauce_lab_cap['screenResolution'] = '2048x1536'
|
||||||
desired_caps['platform'] = "MAC"
|
sauce_lab_cap['captureHtml'] = False
|
||||||
desired_caps['browserName'] = 'Chrome'
|
return sauce_lab_cap
|
||||||
desired_caps['screenResolution'] = '2048x1536'
|
|
||||||
desired_caps['captureHtml'] = False
|
|
||||||
return desired_caps
|
|
||||||
|
|
||||||
@property
|
|
||||||
def environment(self):
|
|
||||||
return pytest.config.getoption('env')
|
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
|
|
||||||
self.errors = []
|
|
||||||
self.cleanup = None
|
|
||||||
|
|
||||||
if self.environment == 'local':
|
|
||||||
options = webdriver.ChromeOptions()
|
|
||||||
options.add_argument('--start-fullscreen')
|
|
||||||
options.add_extension(
|
|
||||||
path.abspath(test_data.config['Paths']['tests_absolute'] + 'resources/metamask3_12_0.crx'))
|
|
||||||
# for chromedriver 2.35
|
|
||||||
self.driver = webdriver.Chrome(chrome_options=options)
|
|
||||||
if self.environment == 'sauce':
|
|
||||||
self.driver = webdriver.Remote(self.executor_sauce_lab,
|
|
||||||
desired_capabilities=self.capabilities_sauce_lab)
|
|
||||||
self.driver.implicitly_wait(5)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def verify_no_errors(self):
|
def verify_no_errors(self):
|
||||||
if self.errors:
|
if self.errors:
|
||||||
|
@ -69,13 +31,115 @@ class BaseTestCase:
|
||||||
msg += (error + '\n')
|
msg += (error + '\n')
|
||||||
pytest.fail(msg, pytrace=False)
|
pytest.fail(msg, pytrace=False)
|
||||||
|
|
||||||
def teardown_method(self):
|
@classmethod
|
||||||
if self.cleanup:
|
def setup_class(cls):
|
||||||
remove_application(self.driver)
|
cls.errors = []
|
||||||
remove_installation(self.driver)
|
cls.environment = pytest.config.getoption('env')
|
||||||
|
|
||||||
|
###################################################################################################################
|
||||||
|
######### Drivers setup
|
||||||
|
###################################################################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Dev Chrome options
|
||||||
|
#
|
||||||
|
cls.capabilities_dev = webdriver.ChromeOptions()
|
||||||
|
cls.capabilities_dev.add_argument('--start-fullscreen')
|
||||||
|
|
||||||
|
#
|
||||||
|
# Org Chrome options
|
||||||
|
#
|
||||||
|
cls.capabilities_org = webdriver.ChromeOptions()
|
||||||
|
# doesn't work on sauce env
|
||||||
|
# cls.capabilities_org.add_extension(path.abspath(test_data.config['Paths']['tests_absolute'] + 'resources/metamask3_12_0.crx'))
|
||||||
|
|
||||||
|
#
|
||||||
|
# SauceLab capabilities
|
||||||
|
#
|
||||||
|
cls.executor_sauce_lab = 'http://%s:%s@ondemand.saucelabs.com:80/wd/hub' % (
|
||||||
|
environ.get('SAUCE_USERNAME'), environ.get('SAUCE_ACCESS_KEY'))
|
||||||
|
drivers = []
|
||||||
|
|
||||||
|
if cls.environment == 'local':
|
||||||
|
for caps in cls.capabilities_dev, cls.capabilities_org:
|
||||||
|
driver = webdriver.Chrome(chrome_options=caps)
|
||||||
|
drivers.append(driver)
|
||||||
|
|
||||||
|
if cls.environment == 'sauce':
|
||||||
|
for caps in cls.capabilities_dev, cls.capabilities_org:
|
||||||
|
cls.get_remote_caps(cls)
|
||||||
|
new_caps = caps.to_capabilities()
|
||||||
|
driver = webdriver.Remote(cls.executor_sauce_lab,
|
||||||
|
desired_capabilities=new_caps)
|
||||||
|
drivers.append(driver)
|
||||||
|
|
||||||
|
for driver in drivers:
|
||||||
|
cls.print_sauce_lab_info(cls, driver)
|
||||||
|
|
||||||
|
cls.driver_dev = drivers[0]
|
||||||
|
cls.driver_org = drivers[1]
|
||||||
|
|
||||||
|
for driver in drivers:
|
||||||
|
driver.implicitly_wait(10)
|
||||||
|
|
||||||
|
###################################################################################################################
|
||||||
|
######### Actions for each driver before class
|
||||||
|
###################################################################################################################
|
||||||
|
|
||||||
|
######ORG
|
||||||
|
landing = LandingPage(cls.driver_org)
|
||||||
|
landing.get_landing_page()
|
||||||
|
|
||||||
|
# Sign Up to SOB
|
||||||
|
cls.github_org = landing.login_button.click()
|
||||||
|
cls.github_org.sign_in(test_data.config['ORG']['gh_login'],
|
||||||
|
test_data.config['ORG']['gh_password'])
|
||||||
|
assert cls.github_org.permission_type.text == 'Personal user data'
|
||||||
|
bounties_page = cls.github_org.authorize_sob.click()
|
||||||
|
|
||||||
|
# SOB Plugin installation and navigate to "Open bounties"
|
||||||
|
cls.github_org.install_sob_plugin()
|
||||||
|
assert bounties_page.bounties_header.text == 'Bounties'
|
||||||
|
assert bounties_page.top_hunters_header.text == 'Top 5 hunters'
|
||||||
|
|
||||||
|
######DEV
|
||||||
|
cls.github_dev = GithubPage(cls.driver_dev)
|
||||||
|
# Sign In to GH as Developer
|
||||||
|
cls.github_dev.get_login_page()
|
||||||
|
cls.github_dev.sign_in(test_data.config['DEV']['gh_login'],
|
||||||
|
test_data.config['DEV']['gh_password'])
|
||||||
|
|
||||||
|
# Fork repo as Developer from Organization
|
||||||
|
cls.github_dev.fork_repo(test_data.config['ORG']['gh_repo'])
|
||||||
|
|
||||||
|
# Cloning repo to local git as Developer and set upstream to Organization (via HTTPS)
|
||||||
|
cls.github_dev.clone_repo(test_data.config['ORG']['gh_repo'],
|
||||||
|
test_data.config['DEV']['gh_username'],
|
||||||
|
test_data.config['ORG']['gh_repo_name'],
|
||||||
|
'git_repo')
|
||||||
|
cls.verify_no_errors(cls)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def teardown_class(cls):
|
||||||
|
|
||||||
|
######ORG
|
||||||
|
|
||||||
|
# SOB Plugin remove installation
|
||||||
|
remove_application(cls.driver_org)
|
||||||
|
remove_installation(cls.driver_org)
|
||||||
|
|
||||||
|
######DEV
|
||||||
|
|
||||||
|
cls.github_dev.delete_fork()
|
||||||
|
cls.github_dev.clean_repo_local_folder()
|
||||||
try:
|
try:
|
||||||
self.print_sauce_lab_info(self.driver)
|
cls.driver_dev.quit()
|
||||||
self.driver.quit()
|
cls.driver_org.quit()
|
||||||
except WebDriverException:
|
except WebDriverException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,30 @@
|
||||||
[Common]
|
[Common]
|
||||||
;app URL
|
;app URL
|
||||||
url = https://openbounty.status.im:444/
|
url = https://openbounty.status.im:444/
|
||||||
|
;URL to GH openbounty app
|
||||||
|
sob_test_app = http://github.com/apps/status-open-bounty-app-test
|
||||||
|
gh_login = https://github.com/login
|
||||||
[Paths]
|
[Paths]
|
||||||
;AbsolutePath to 'tests' folder
|
;AbsolutePath to 'end-to-end' folder
|
||||||
tests_absolute = /usr/dir/open-bounty/test/end-to-end/tests/
|
tests_absolute = /usr/dir/open-bounty/test/end-to-end/
|
||||||
[ORG]
|
[ORG]
|
||||||
;GitHub credentials for organization
|
|
||||||
|
;GitHub credentials for organization owner
|
||||||
gh_login = login
|
gh_login = login
|
||||||
gh_password = password
|
gh_password = password
|
||||||
|
;GitHub organization path
|
||||||
|
gh_org_profile = https://github.com/organizations/organization/
|
||||||
|
;GitHub repo path
|
||||||
|
gh_repo = https://github.com/org_name/repo_name/
|
||||||
|
;GitHub repo name
|
||||||
|
gh_repo_name = repo_name
|
||||||
|
|
||||||
;MetaMask password for organization
|
;MetaMask password for organization
|
||||||
mm_password = password
|
mm_password = password
|
||||||
|
|
||||||
|
[DEV]
|
||||||
|
;GitHub credentials for developer
|
||||||
|
gh_login = login
|
||||||
|
gh_password = password
|
||||||
|
gh_username = username
|
||||||
|
gh_forked_repo = https://github.com/username/reponame/
|
|
@ -1,5 +1,6 @@
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
|
from tests import test_data
|
||||||
|
|
||||||
|
|
||||||
def remove_application(driver):
|
def remove_application(driver):
|
||||||
|
@ -13,7 +14,7 @@ def remove_application(driver):
|
||||||
|
|
||||||
def remove_installation(driver):
|
def remove_installation(driver):
|
||||||
try:
|
try:
|
||||||
driver.get('https://github.com/organizations/Org4/settings/installations')
|
driver.get(test_data.config['ORG']['gh_org_profile'] + 'settings/installations')
|
||||||
driver.find_element(By.CSS_SELECTOR, '.iconbutton').click()
|
driver.find_element(By.CSS_SELECTOR, '.iconbutton').click()
|
||||||
driver.find_element(By.XPATH, "//a[@class='btn btn-danger']").click()
|
driver.find_element(By.XPATH, "//a[@class='btn btn-danger']").click()
|
||||||
driver.find_element(By.CSS_SELECTOR, '.facebox-popup .btn-danger').click()
|
driver.find_element(By.CSS_SELECTOR, '.facebox-popup .btn-danger').click()
|
||||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
||||||
from os import environ
|
from os import environ
|
||||||
from pages.openbounty.landing import LandingPage
|
from pages.openbounty.landing import LandingPage
|
||||||
from pages.openbounty.bounties import BountiesPage
|
from pages.openbounty.bounties import BountiesPage
|
||||||
|
from pages.thirdparty.github import GithubPage
|
||||||
from tests.basetestcase import BaseTestCase
|
from tests.basetestcase import BaseTestCase
|
||||||
from tests import test_data
|
from tests import test_data
|
||||||
|
|
||||||
|
@ -10,28 +11,13 @@ from tests import test_data
|
||||||
class TestLogin(BaseTestCase):
|
class TestLogin(BaseTestCase):
|
||||||
|
|
||||||
def test_deploy_new_contract(self):
|
def test_deploy_new_contract(self):
|
||||||
self.cleanup = True
|
|
||||||
landing = LandingPage(self.driver)
|
|
||||||
landing.get_landing_page()
|
|
||||||
|
|
||||||
# Sign Up to SOB
|
|
||||||
github = landing.login_button.click()
|
|
||||||
github.sign_in(test_data.config['ORG']['gh_login'],
|
|
||||||
test_data.config['ORG']['gh_password'])
|
|
||||||
assert github.permission_type.text == 'Personal user data'
|
|
||||||
bounties_page = github.authorize_sob.click()
|
|
||||||
|
|
||||||
# SOB Plugin installation and navigate to "Open bounties"
|
|
||||||
github.install_sob_plugin()
|
|
||||||
assert bounties_page.bounties_header.text == 'Bounties'
|
|
||||||
assert bounties_page.top_hunters_header.text == 'Top 5 hunters'
|
|
||||||
|
|
||||||
# Waiting for deployed contract; test_data.issue created here
|
# Waiting for deployed contract; test_data.issue created here
|
||||||
github.create_new_bounty()
|
self.github_org.create_new_bounty()
|
||||||
github.get_deployed_contract()
|
self.github_org.get_deployed_contract()
|
||||||
|
|
||||||
# Navigate and check top bounty in "Open bounties"
|
# Navigate and check top bounty in "Open bounties"
|
||||||
bounties_page = BountiesPage(self.driver)
|
bounties_page = BountiesPage(self.driver_org)
|
||||||
bounties_page.get_bounties_page()
|
bounties_page.get_bounties_page()
|
||||||
titles = bounties_page.bounty_titles.find_elements()
|
titles = bounties_page.bounty_titles.find_elements()
|
||||||
assert titles[0].text == test_data.issue['title']
|
assert titles[0].text == test_data.issue['title']
|
||||||
|
@ -40,3 +26,6 @@ class TestLogin(BaseTestCase):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue