From 417018572ed84bb047cd1542b93f07c542555977 Mon Sep 17 00:00:00 2001 From: Churikova Tetiana Date: Mon, 5 Feb 2018 16:14:28 +0200 Subject: [PATCH] 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() + +