This commit is contained in:
Vitaliy Vlasov 2018-02-12 15:37:05 +02:00 committed by GitHub
commit c3798e98d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 303 additions and 106 deletions

View File

@ -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.

View File

@ -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)))

View File

@ -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]]))))
))

View File

@ -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"]

View File

@ -0,0 +1,5 @@
(ns commiteth.util
(:require [clojure.string :as string]))
(defn os-windows? []
(string/includes? (-> js/navigator .-platform) "Win"))

View File

@ -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;
} }

View File

@ -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')

View File

@ -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()

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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/

View File

@ -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()

View File

@ -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):