From 417317f9b5b37e9ee618ae9559dc9aedb4b7a7fd Mon Sep 17 00:00:00 2001 From: Churikova Tetiana Date: Fri, 26 Jan 2018 20:12:58 +0200 Subject: [PATCH 1/5] test for forking repo and cloning it to local repo --- test/end-to-end/pages/base_page.py | 4 ++ test/end-to-end/pages/thirdparty/github.py | 81 +++++++++++++++++++++- test/end-to-end/requirements.txt | 3 + test/end-to-end/tests/__init__.py | 10 +-- test/end-to-end/tests/config_example.ini | 16 ++++- test/end-to-end/tests/test_contracts.py | 21 ++++++ 6 files changed, 127 insertions(+), 8 deletions(-) diff --git a/test/end-to-end/pages/base_page.py b/test/end-to-end/pages/base_page.py index de61cd4..9bc6a21 100644 --- a/test/end-to-end/pages/base_page.py +++ b/test/end-to-end/pages/base_page.py @@ -15,3 +15,7 @@ class BasePageObject(object): @property def time_now(self): return datetime.now().strftime('%-m%-d%-H%-M%-S') + + @property + def current_url(self): + return self.driver.current_url diff --git a/test/end-to-end/pages/thirdparty/github.py b/test/end-to-end/pages/thirdparty/github.py index 0d00335..3607bc9 100644 --- a/test/end-to-end/pages/thirdparty/github.py +++ b/test/end-to-end/pages/thirdparty/github.py @@ -2,6 +2,10 @@ import time, pytest from pages.base_element import * from pages.base_page import BasePageObject from tests import test_data +from git import Repo +import os +import shutil +import logging class EmailEditbox(BaseEditBox): @@ -106,6 +110,32 @@ class ContractBody(BaseText): super(ContractBody, self).__init__(driver) self.locator = self.Locator.xpath_selector("//tbody//p[contains(text(), " "'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 GithubPage(BasePageObject): @@ -133,18 +163,28 @@ class GithubPage(BasePageObject): self.cross_button = LabelsButton.CrossButton(self.driver) self.submit_new_issue_button = SubmitNewIssueButton(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) + 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): - 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): self.email_input.send_keys(email) self.password_input.send_keys(password) self.sign_in_button.click() + def install_sob_plugin(self): initial_url = self.driver.current_url self.get_sob_plugin_page() @@ -164,7 +204,19 @@ class GithubPage(BasePageObject): self.bounty_label.click() self.cross_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 id is %s" % test_data.issue['id']) + 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): for i in range(wait): @@ -175,3 +227,26 @@ class GithubPage(BasePageObject): time.sleep(10) pass 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) + + + diff --git a/test/end-to-end/requirements.txt b/test/end-to-end/requirements.txt index 397c508..32b99e7 100644 --- a/test/end-to-end/requirements.txt +++ b/test/end-to-end/requirements.txt @@ -16,3 +16,6 @@ selenium==2.53.6 six==1.10.0 urllib3==1.22 yarl==0.12.0 +gitpython==2.1.8 +gitdb2==2.0.3 +smmap2==2.0.3 \ No newline at end of file diff --git a/test/end-to-end/tests/__init__.py b/test/end-to-end/tests/__init__.py index 41ae6be..9d59efe 100644 --- a/test/end-to-end/tests/__init__.py +++ b/test/end-to-end/tests/__init__.py @@ -3,15 +3,17 @@ import configparser class TestData(object): def __init__(self): - self.test_name = None self.config = configparser.ConfigParser() # define here path to your config.ini file - #example - config_example.ini + # example - config_example.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() diff --git a/test/end-to-end/tests/config_example.ini b/test/end-to-end/tests/config_example.ini index 4b52a24..e807118 100644 --- a/test/end-to-end/tests/config_example.ini +++ b/test/end-to-end/tests/config_example.ini @@ -1,13 +1,27 @@ [Common] ;app URL 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] ;AbsolutePath to 'tests' folder tests_absolute = /usr/dir/open-bounty/test/end-to-end/tests/ [ORG] -;GitHub credentials for organization + +;GitHub credentials for organization owner gh_login = login gh_password = password +;GitHub repo path +gh_repo = https://github.com/org_name/repo_name/ +;GitHub repo name +gh_repo_name = repo_name + ;MetaMask password for organization mm_password = password +[DEV] +;GitHub credentials for developer +gh_login = login +gh_password = password +gh_username = username \ No newline at end of file diff --git a/test/end-to-end/tests/test_contracts.py b/test/end-to-end/tests/test_contracts.py index 5564b7b..05cc539 100644 --- a/test/end-to-end/tests/test_contracts.py +++ b/test/end-to-end/tests/test_contracts.py @@ -2,6 +2,7 @@ import pytest from os import environ from pages.openbounty.landing import LandingPage from pages.openbounty.bounties import BountiesPage +from pages.thirdparty.github import GithubPage from tests.basetestcase import BaseTestCase from tests import test_data @@ -37,6 +38,26 @@ class TestLogin(BaseTestCase): assert titles[0].text == test_data.issue['title'] + def test_forking_repo(self): + github = GithubPage(self.driver) + self.cleanup = True + + # Sign In to GH as Developer + github.get_login_page() + github.sign_in(test_data.config['DEV']['gh_login'], + test_data.config['DEV']['gh_password']) + + # Fork repo as Developer from Organization + github.fork_repo(test_data.config['ORG']['gh_repo']) + + # Cloning repo to local git as Developer and set upstream to Organization (via HTTPS) + github.clone_repo(test_data.config['ORG']['gh_repo'], + test_data.config['DEV']['gh_username'], + test_data.config['ORG']['gh_repo_name'], + 'git_repo') + + github.clean_repo_local_folder() + From 417018572ed84bb047cd1542b93f07c542555977 Mon Sep 17 00:00:00 2001 From: Churikova Tetiana Date: Mon, 5 Feb 2018 16:14:28 +0200 Subject: [PATCH 2/5] add ability to delete fork; rework BaseTestCase to use 2 drivers and setup\teardown classmethods; move all preconditions for tests to setup\teardown classmethods. --- test/end-to-end/pages/thirdparty/github.py | 26 ++- test/end-to-end/tests/__init__.py | 1 + test/end-to-end/tests/basetestcase.py | 175 ++++++++++++++------- test/end-to-end/tests/config_example.ini | 9 +- test/end-to-end/tests/postconditions.py | 3 +- test/end-to-end/tests/test_contracts.py | 42 +---- 6 files changed, 159 insertions(+), 97 deletions(-) diff --git a/test/end-to-end/pages/thirdparty/github.py b/test/end-to-end/pages/thirdparty/github.py index 3607bc9..60333be 100644 --- a/test/end-to-end/pages/thirdparty/github.py +++ b/test/end-to-end/pages/thirdparty/github.py @@ -136,7 +136,20 @@ class ForkedRepoText(BaseText): 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): def __init__(self, driver): @@ -169,6 +182,10 @@ class GithubPage(BasePageObject): 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): self.driver.get(test_data.config['ORG']['gh_repo'] + 'issues') @@ -205,7 +222,6 @@ class GithubPage(BasePageObject): self.cross_button.click() self.submit_new_issue_button.click() test_data.issue['id'] = self.issue_id.text[1:] - logging.info("Issue id is %s" % test_data.issue['id']) logging.info("Issue title is %s" % test_data.issue['title']) def fork_repo(self, initial_repo, wait=60): @@ -248,5 +264,13 @@ class GithubPage(BasePageObject): 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() + + + diff --git a/test/end-to-end/tests/__init__.py b/test/end-to-end/tests/__init__.py index 9d59efe..49b8c0e 100644 --- a/test/end-to-end/tests/__init__.py +++ b/test/end-to-end/tests/__init__.py @@ -3,6 +3,7 @@ import configparser class TestData(object): def __init__(self): + self.test_name = None self.config = configparser.ConfigParser() # define here path to your config.ini file diff --git a/test/end-to-end/tests/basetestcase.py b/test/end-to-end/tests/basetestcase.py index 9ba9409..3f618b6 100644 --- a/test/end-to-end/tests/basetestcase.py +++ b/test/end-to-end/tests/basetestcase.py @@ -4,63 +4,25 @@ from selenium.common.exceptions import WebDriverException from tests.postconditions import remove_application, remove_installation from os import environ, path from tests import test_data - +from pages.thirdparty.github import GithubPage +from pages.openbounty.landing import LandingPage 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): sys.stdout = sys.stderr print("SauceOnDemandSessionID=%s job-name=%s" % (driver.session_id, pytest.config.getoption('build'))) - - @property - def capabilities_sauce_lab(self): - - desired_caps = dict() - desired_caps['name'] = test_data.test_name - desired_caps['build'] = pytest.config.getoption('build') - desired_caps['platform'] = "MAC" - desired_caps['browserName'] = 'Chrome' - 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 return_caps(self): + sauce_lab_cap = dict() + sauce_lab_cap['name'] = test_data.test_name + sauce_lab_cap['build'] = pytest.config.getoption('build') + sauce_lab_cap['platform'] = "MAC" + sauce_lab_cap['browserName'] = 'Chrome' + sauce_lab_cap['screenResolution'] = '2048x1536' + sauce_lab_cap['captureHtml'] = False + return sauce_lab_cap def verify_no_errors(self): if self.errors: @@ -69,13 +31,116 @@ class BaseTestCase: msg += (error + '\n') pytest.fail(msg, pytrace=False) - def teardown_method(self): - if self.cleanup: - remove_application(self.driver) - remove_installation(self.driver) + @classmethod + def setup_class(cls): + cls.errors = [] + 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')) + + cls.return_caps(cls) + sauce_lab_cap_dev = cls.capabilities_dev.to_capabilities() + cls.capabilities_sauce_lab_dev = sauce_lab_cap_dev + + cls.return_caps(cls) + sauce_lab_cap_org = cls.capabilities_org.to_capabilities() + cls.capabilities_sauce_lab_org = sauce_lab_cap_org + + + if cls.environment == 'local': + cls.driver_dev = webdriver.Chrome(chrome_options=cls.capabilities_dev) + cls.driver_org = webdriver.Chrome(chrome_options=cls.capabilities_org) + + if cls.environment == 'sauce': + cls.driver_dev = webdriver.Remote(cls.executor_sauce_lab, + desired_capabilities=cls.capabilities_sauce_lab_dev) + cls.print_sauce_lab_info(cls, cls.driver_dev) + cls.driver_org = webdriver.Remote(cls.executor_sauce_lab, + desired_capabilities=cls.capabilities_sauce_lab_org) + cls.print_sauce_lab_info(cls, cls.driver_org) + + for driver in cls.driver_dev, cls.driver_org: + 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: - self.print_sauce_lab_info(self.driver) - self.driver.quit() + cls.driver_dev.quit() + cls.driver_org.quit() except WebDriverException: pass + + + diff --git a/test/end-to-end/tests/config_example.ini b/test/end-to-end/tests/config_example.ini index e807118..6d2f8c3 100644 --- a/test/end-to-end/tests/config_example.ini +++ b/test/end-to-end/tests/config_example.ini @@ -5,13 +5,15 @@ url = https://openbounty.status.im:444/ sob_test_app = http://github.com/apps/status-open-bounty-app-test gh_login = https://github.com/login [Paths] -;AbsolutePath to 'tests' folder -tests_absolute = /usr/dir/open-bounty/test/end-to-end/tests/ +;AbsolutePath to 'end-to-end' folder +tests_absolute = /usr/dir/open-bounty/test/end-to-end/ [ORG] ;GitHub credentials for organization owner gh_login = login 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 @@ -24,4 +26,5 @@ mm_password = password ;GitHub credentials for developer gh_login = login gh_password = password -gh_username = username \ No newline at end of file +gh_username = username +gh_forked_repo = https://github.com/username/reponame/ \ No newline at end of file diff --git a/test/end-to-end/tests/postconditions.py b/test/end-to-end/tests/postconditions.py index b9f4c7d..1b09d42 100644 --- a/test/end-to-end/tests/postconditions.py +++ b/test/end-to-end/tests/postconditions.py @@ -1,5 +1,6 @@ from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException +from tests import test_data def remove_application(driver): @@ -13,7 +14,7 @@ def remove_application(driver): def remove_installation(driver): 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.XPATH, "//a[@class='btn btn-danger']").click() driver.find_element(By.CSS_SELECTOR, '.facebox-popup .btn-danger').click() diff --git a/test/end-to-end/tests/test_contracts.py b/test/end-to-end/tests/test_contracts.py index 05cc539..17c66e2 100644 --- a/test/end-to-end/tests/test_contracts.py +++ b/test/end-to-end/tests/test_contracts.py @@ -11,52 +11,20 @@ from tests import test_data class TestLogin(BaseTestCase): 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 - github.create_new_bounty() - github.get_deployed_contract() + self.github_org.create_new_bounty() + self.github_org.get_deployed_contract() # Navigate and check top bounty in "Open bounties" - bounties_page = BountiesPage(self.driver) + bounties_page = BountiesPage(self.driver_org) bounties_page.get_bounties_page() titles = bounties_page.bounty_titles.find_elements() assert titles[0].text == test_data.issue['title'] - def test_forking_repo(self): - github = GithubPage(self.driver) - self.cleanup = True - - # Sign In to GH as Developer - github.get_login_page() - github.sign_in(test_data.config['DEV']['gh_login'], - test_data.config['DEV']['gh_password']) - - # Fork repo as Developer from Organization - github.fork_repo(test_data.config['ORG']['gh_repo']) - - # Cloning repo to local git as Developer and set upstream to Organization (via HTTPS) - github.clone_repo(test_data.config['ORG']['gh_repo'], - test_data.config['DEV']['gh_username'], - test_data.config['ORG']['gh_repo_name'], - 'git_repo') - - github.clean_repo_local_folder() + + From ccf3fcc485812b4dbcc83ebe273b024125eb464d Mon Sep 17 00:00:00 2001 From: Churikova Tetiana Date: Tue, 6 Feb 2018 12:58:13 +0200 Subject: [PATCH 3/5] add ability to delete fork; rework BaseTestCase to use 2 drivers and setup\teardown classmethods; move all preconditions for tests to setup\teardown classmethods. --- test/end-to-end/pages/base_page.py | 3 -- test/end-to-end/tests/basetestcase.py | 45 +++++++++++++-------------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/test/end-to-end/pages/base_page.py b/test/end-to-end/pages/base_page.py index 9bc6a21..f602775 100644 --- a/test/end-to-end/pages/base_page.py +++ b/test/end-to-end/pages/base_page.py @@ -16,6 +16,3 @@ class BasePageObject(object): def time_now(self): return datetime.now().strftime('%-m%-d%-H%-M%-S') - @property - def current_url(self): - return self.driver.current_url diff --git a/test/end-to-end/tests/basetestcase.py b/test/end-to-end/tests/basetestcase.py index 3f618b6..aa113c4 100644 --- a/test/end-to-end/tests/basetestcase.py +++ b/test/end-to-end/tests/basetestcase.py @@ -14,7 +14,7 @@ class BaseTestCase: sys.stdout = sys.stderr print("SauceOnDemandSessionID=%s job-name=%s" % (driver.session_id, pytest.config.getoption('build'))) - def return_caps(self): + def get_remote_caps(self): sauce_lab_cap = dict() sauce_lab_cap['name'] = test_data.test_name sauce_lab_cap['build'] = pytest.config.getoption('build') @@ -36,9 +36,9 @@ class BaseTestCase: cls.errors = [] cls.environment = pytest.config.getoption('env') -########################################################################################################################################################## +################################################################################################################### ######### Drivers setup -########################################################################################################################################################## +################################################################################################################### # # Dev Chrome options @@ -58,34 +58,33 @@ class BaseTestCase: # cls.executor_sauce_lab = 'http://%s:%s@ondemand.saucelabs.com:80/wd/hub' % ( environ.get('SAUCE_USERNAME'), environ.get('SAUCE_ACCESS_KEY')) - - cls.return_caps(cls) - sauce_lab_cap_dev = cls.capabilities_dev.to_capabilities() - cls.capabilities_sauce_lab_dev = sauce_lab_cap_dev - - cls.return_caps(cls) - sauce_lab_cap_org = cls.capabilities_org.to_capabilities() - cls.capabilities_sauce_lab_org = sauce_lab_cap_org - + drivers = [] if cls.environment == 'local': - cls.driver_dev = webdriver.Chrome(chrome_options=cls.capabilities_dev) - cls.driver_org = webdriver.Chrome(chrome_options=cls.capabilities_org) + for caps in cls.capabilities_dev, cls.capabilities_org: + driver = webdriver.Chrome(chrome_options=caps) + drivers.append(driver) if cls.environment == 'sauce': - cls.driver_dev = webdriver.Remote(cls.executor_sauce_lab, - desired_capabilities=cls.capabilities_sauce_lab_dev) - cls.print_sauce_lab_info(cls, cls.driver_dev) - cls.driver_org = webdriver.Remote(cls.executor_sauce_lab, - desired_capabilities=cls.capabilities_sauce_lab_org) - cls.print_sauce_lab_info(cls, cls.driver_org) + 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 cls.driver_dev, cls.driver_org: + 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) From 1a4aec81d75444f48a1b9dba9a3deffc64e72072 Mon Sep 17 00:00:00 2001 From: pablodip Date: Wed, 7 Feb 2018 12:23:44 +0100 Subject: [PATCH 4/5] fix some visual issues in filters --- src/less/style.less | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/less/style.less b/src/less/style.less index 6fb2407..0717841 100644 --- a/src/less/style.less +++ b/src/less/style.less @@ -508,7 +508,10 @@ margin: 14.5px 0; } input[type=range]:focus { - outline: none; + outline: 0; + } + input[type=range]::-moz-focus-outer { + border: 0; } input[type=range]::-webkit-slider-runnable-track { width: 100%; @@ -635,11 +638,6 @@ outline: none; } - input { - background: green; - transform: scale(1.3); - } - input:hover { cursor: pointer; } From 27d189f1bc0c24c9fc466b4e5571a1a7396e1a90 Mon Sep 17 00:00:00 2001 From: Vitaliy Vlasov Date: Thu, 8 Feb 2018 11:31:46 +0200 Subject: [PATCH 5/5] Revert "Revert "[FIX #187] Fix address dropdown in My Payment Details"" --- src/cljs/commiteth/common.cljs | 15 ++++++++------- src/cljs/commiteth/handlers.cljs | 2 +- src/cljs/commiteth/update_address.cljs | 25 +++++++++++++++++++------ 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/cljs/commiteth/common.cljs b/src/cljs/commiteth/common.cljs index 1213395..4399156 100644 --- a/src/cljs/commiteth/common.cljs +++ b/src/cljs/commiteth/common.cljs @@ -12,16 +12,17 @@ :on-change #(reset! val-ratom (-> % .-target .-value))})])) (defn dropdown [props title val-ratom items] + "If val-ratom is set, preselect it in the dropdown. + Otherwise, prepend title as a disabled option." (fn [] - (if (= 1 (count items)) - (reset! val-ratom (first items))) [:select.ui.basic.selection.dropdown (merge props {:on-change - #(reset! val-ratom (-> % .-target .-value))}) - (doall (for [item items] - ^{:key item} [:option - {:value item} - item]))])) + #(reset! val-ratom (-> % .-target .-value)) + :default-value (or @val-ratom title)}) + (for [item items] + ^{:key item} [:option {:value item + :disabled (= item title)} + item])])) (defn moment-timestamp [time] (let [now (.now js/Date.) diff --git a/src/cljs/commiteth/handlers.cljs b/src/cljs/commiteth/handlers.cljs index eb61374..ed677d7 100644 --- a/src/cljs/commiteth/handlers.cljs +++ b/src/cljs/commiteth/handlers.cljs @@ -327,7 +327,7 @@ :http {:method POST :url "/api/user/address" :on-success #(do - (dispatch [:assoc-in [:user [:address] address]]) + (dispatch [:assoc-in [:user :address] address]) (dispatch [:set-flash-message :success "Address saved"])) diff --git a/src/cljs/commiteth/update_address.cljs b/src/cljs/commiteth/update_address.cljs index 6134bde..14ceaa1 100644 --- a/src/cljs/commiteth/update_address.cljs +++ b/src/cljs/commiteth/update_address.cljs @@ -3,6 +3,7 @@ [commiteth.common :refer [input dropdown]] [reagent.core :as r] [reagent.crypt :as crypt] + [clojure.string :as str] [cljs-web3.eth :as web3-eth])) @@ -22,13 +23,25 @@ [:p "Insert your Ethereum address in hex format."] [:div.field (if-not (empty? web3-accounts) - [dropdown {:class "address-input"} "Select address" - address - (vec - (for [acc web3-accounts] - acc))] + ; Add value of address if it's missing from items list. + ; If address is empty, add title + (let [accounts (map str/lower-case web3-accounts) + addr @address + title "Select address" + addr-not-in-web3? (and addr (as-> web3-accounts acc + (map str/lower-case acc) + (set acc) + (contains? acc addr) + (not acc))) + items (cond->> web3-accounts + addr-not-in-web3? (into [addr]) + (not addr) (into [title]))] + [dropdown {:class "address-input"} + title + address + items]) [:div.ui.input.address-input - [input address {:placeholder "0x0000000000000000000000000000000000000000" + [input address {:placeholder "0x0000000000000000000000000000000000000000" :auto-complete "off" :auto-correct "off" :spell-check "false"