def test_import_taxonomy_id(self): """ Test verifies that taxonomy ID is correctly imported from Etsy (taxonomy_path or deprecated category_path are no longer used). Note: In API communication only taxonomy is used, but the text in UI is still called "Category". """ expected_db_task_queue = [ ['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', ''] ] expected_taxonomy_id = [['1', '2390']] self.stop_all() self.set_etsy_testcase('listings_sync_category') run_sql('HIVE', 'listings_10', retry=2) self.restart_all() # after restart the listing is synced from etsy emulator # with different taxonomy path than before # check that syncShop task and download product tasks are done wait_for_assert( expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that taxonomy path and id were imported correctly taxonomy_id = run_sql('HIVE', 'select_taxonomy_id', True) assert taxonomy_id == expected_taxonomy_id
def setup_class(self): super().setup_class(self) self.stop_all(self) # we can afford to load data to DB once, DB is not changed in tests in this class run_sql('HIVE', 'listings_empty', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all(self)
def test_main_draft_inactive_listing_data(self): """ Test verifies that: - all data of a draft listing are displayed correctly on the main page - all data of an inactive listing are displayed correctly on the main page """ expected_listings_texts_draft = [DRAFT_TITLE, '65', '$95.00', '1/1/17', 'Summer Sale'] expected_listings_texts_inactive = [INACTIVE_TITLE, '65', '$95.00', '1/5/18', 'Summer Sale'] run_sql('HIVE', 'listings_09', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all() lp = LoginPage(self.driver) lp.login(page=self.login_url_http) mp = MainPage(self.driver) mp.get_main(self.base_url) # --- check Draft listings --- mp.select_filter_tab('Draft') listing_texts = mp.listing_texts(DRAFT_TITLE) assert listing_texts == expected_listings_texts_draft # --- check Inactive listings --- mp.select_filter_tab('Inactive') listing_texts = mp.listing_texts(INACTIVE_TITLE) assert listing_texts == expected_listings_texts_inactive
def test_etsy_null_character(self): """ Test verifies that listing is successfully imported when it has null character in description. Null character is ignored during import - see HIVE-1477 """ expected_descriptions = [ 'Description with null character', 'Description without null character' ] self.set_etsy_testcase('listings_null_character') self.stop_all() run_sql('HIVE', 'listings_no_shop', retry=2) setup_rabbit() self.restart_all() # login and import shop lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) lpg.go_to_etsy() lpg.wait_during_sync_from_etsy() # check that two listings were imported db_data = run_sql('HIVE', 'select_description', True) assert len( db_data) == 2, 'Unexpected count of successfully imported listings' # check that descriptions were correctly imported for both listings descriptions = sorted([row[0] for row in db_data]) assert descriptions == expected_descriptions, 'Unexpected descriptions of listings'
def setup_class(self): super().setup_class(self) self.stop_all(self) self.set_etsy_testcase(self, 'tc1') run_sql('HIVE', 'listings_03', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all(self)
def test_etsy_invalid_section(self): """ Test verifies, that invalid data from Etsy - null title in section - don't cause syncShop task to be failed. See HIVE-934 for more info. """ expected_db_data = [ ['1', 'syncShop', '2', 'done', ''], ] expected_db_data_sections = [['1', '2', '15183328', 'On Sale'], ['2', '2', '15180189', 'Holiday Gifts'], ['3', '2', '17365192', 'Summer Sale'], ['4', '2', '18790753', 'de'], ['5', '2', '18787742', 'bbbaa'], ['6', '2', '18790755', 'eeee']] self.stop_all() self.set_etsy_testcase('listings_invalid_section') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_data, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that sections are synced correctly - invalid section is ignored data = run_sql('HIVE', 'select_sections', True) assert data == expected_db_data_sections
def test_etsy_missing_title(self): """ Test verifies, that invalid data from Etsy - missing title - don't cause syncShop task to be suspended. See HIVE-845 for more info """ expected_db_task_queue = [['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', '']] expected_db_product_properties = [[ '1', '2', 't', 'Title cannot be empty' ]] self.stop_all() self.set_etsy_testcase('listings_missing_title') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that product was marked as invalid and check the reason why data_db_product_properties = run_sql('HIVE', 'select_product_properties', True) assert expected_db_product_properties == data_db_product_properties
def test_etsy_listing_unavailable(self): """ Test verifies that shopSync task finishes correctly when a listing has status 'unavailable'. Such a listing does not contain all fields that listing should contain, i.e. title, price, quantity, therefore it is marked as invalid. See HIVE-1038 and HIVE-1046 for more info """ expected_db_task_queue = [['1', 'syncShop', '2', 'done', ''], ['2', 'downloadProduct', '1', 'done', '']] expected_db_product_properties = [[ '1', '2', 't', 'Unsupported listing state: unavailable' ]] self.stop_all() self.set_etsy_testcase('listings_status_unavailable') run_sql('HIVE', 'listings_10', retry=2) setup_rabbit() self.restart_all() # check that sync task is done wait_for_assert(expected_db_task_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected') # check that product was marked as invalid and check the reason why data_db_product_properties = run_sql('HIVE', 'select_product_properties', True) assert expected_db_product_properties == data_db_product_properties
def import_shop(self, etsy_test_case, timeout_sec=30): """ Import shop from etsy emulator to Hive :param etsy_test_case: name of etsy test case - conforms to its json file :param timeout_sec: timeout for importing the shop """ self._used_etsy_testcase = etsy_test_case self.set_etsy_testcase(etsy_test_case) self.stop_all() run_sql('HIVE', 'listings_no_shop', retry=2) self.restart_all() d = self.driver d.delete_all_cookies() lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) lpg.go_to_etsy() vela.wait_for_shop_to_sync(expected_status='up_to_date', timeout_sec=timeout_sec) self.stop_all() assert self.db.get_shop_status(2) == 'up_to_date'
def wait_for_shop_to_sync(last_sync_time: arrow.Arrow = None, expected_status: str = None, timeout_sec: int = 30): """ Waits for shop under test to sync, either according to shop status or according to last sync timestamp. :param last_sync_time: timestamp of previous sync of the shop, as an Arrow object :param expected_status: expected end status of the shop :param timeout_sec: timeout for the wait operation """ assert last_sync_time or expected_status, 'Choose at least one parameter' # if we are importing a shop, should might not have a record yet in the shops table, wait for it wait_for_assert(1, lambda: len(run_sql('HIVE', 'select_shop_status', True))) if last_sync_time: wait_for_assert(last_sync_time, get_shop_last_sync_time, oper=operator.lt, delay_sec=1, retries=timeout_sec, message='Shop not synced') if expected_status: expected_db_shop_status = [expected_status, 'f', ''] wait_for_assert( expected_db_shop_status, lambda: run_sql('HIVE', 'select_shop_status', True)[0][1:], "Shop sync not finished", delay_sec=1, retries=timeout_sec)
def test_add_shop_basic(self): expected_data = [ [ '100001', 'VarTEST Tangle Free Headphones w/mic Earbuds, Custom Wrapped Match Your Phone Case iPhone 6 Plus 5 4 iPad iPod Android Smartphone Phone', 'draft' ], [ '100002', 'Vartest TEST Sea Tangle Free Earbuds iPhone Android Tablets iPod by MyBuds', 'draft' ], [ '100003', 'Vartest TEST SALE! Wild Berry Wrapped Earbuds or EarPods for iPhone/Android', 'draft' ], [ '100006', 'MC Test Hand Built Ring Catchers The Perfect Party Favor for Your Next Event megha', 'inactive' ] ] self.set_etsy_testcase('listings_09') self.stop_all() run_sql('HIVE', 'listings_no_shop', retry=2) self.restart_all() lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) lpg.go_to_etsy() lpg.wait_during_sync_from_etsy() d = self.driver pg = MainPage(d) # check the menu contais the shop channel_button = pg.channel_button() click(channel_button) wait_for_web_assert('ETSYGetvelaTest2', lambda: channel_button.text) menu_items = d.find_elements_by_css_selector('div.shops-menu li') assert len(menu_items) == 1 assert (menu_items[0].is_displayed()) shop_names = [t.text for t in menu_items] assert shop_names == ['GetvelaTest2'] # number of listings ['Active', 'Draft', 'Inactive'], Note: expired listings are not imported listing_counts_by_status = [t.text for t in pg.filter_tabs_counts()] assert listing_counts_by_status == ['0', '3', '1'] # Check imported listings - basic data data = run_sql('HIVE', 'select_product_short_info', True) assert data == expected_data, 'Unexpected product data in DB'
def setup_class(self): super().setup_class(self) self.stop_all(self) self.set_etsy_testcase(self, 'tc1') # as the DB is not changed in tests we can afford to fill it only once run_sql('HIVE', "listings_03", retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all(self)
def check_db_state(expected_product_offerings, expected_variation_properties, expected_variation_options): wait_for_assert(expected_product_offerings, lambda: run_sql('HIVE', 'select_product_offerings_short', True), 'Product offerings in DB are incorrect') variation_properties = run_sql('HIVE', 'select_variation_properties', True) assert variation_properties == expected_variation_properties variation_options = run_sql('HIVE', 'select_variation_options', True) assert variation_options == expected_variation_options
def setup_class(self): super().setup_class(self) try: self.stop_all(self) self.set_etsy_testcase(self, 'tc1') run_sql('HIVE', "listings_03", retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all(self) except Exception as e: print('*** setup_class failed: ' + str(e) + ' ***') raise
def reload(request): """ stop servers, init etsy emulator, load `self.sql_file` to the db, start servers """ self = request.node.parent.obj self.stop_all() try: etsy_testcase = self.etsy_testcase except AttributeError: etsy_testcase = 'tc1' self.set_etsy_testcase(etsy_testcase) run_sql('HIVE', self.sql_file, retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all() self.driver.get(self.base_url)
def setup_method(self, method): super().setup_method(method) self.stop_all() run_sql('HIVE', 'listings_03', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) setup_rabbit() self.restart_all() lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) d = self.driver pg = MainPage(d) pg.get_main(self.base_url) pg.select_filter_tab('Active')
def test_sync_updates_title(self): """ Tests that data is written to the database when [Sync Updates] is clicked It also tests that data are correctly processed in more than one batch (see HIVE-1216). """ # Configure Hive to process changes in batches of two listings # Env variable must be set before Hive is started os.environ['SYNC_UPDATES_BATCH_SIZE'] = '2' expected_data = [['1', 'hello First something 1234 (1)'], ['2', 'hello Second something 1235 (2)'], ['3', 'hello Third something LG-512a (3)']] select_listings_to_edit(self.driver) bp = BulkPage(self.driver) input_field = bp.operation_input() send_keys(input_field, 'hello ') # click on Apply and check Apply button click(bp.operation_apply()) wait_for_web_assert(False, bp.operation_apply().is_enabled, 'Apply button is enabled') # Sync changes click(bp.sync_updates_button()) # Check data in DB wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_title_modified', True), 'Unexpected title data in DB')
def test_sync_updates_tags(self): """ Tests that data is written to the database when [Sync Updates] is clicked """ expected_data = [['1', '{Tag01,AAA,BBB,CCC}'], ['2', '{Tag01,AAA,BBB,CCC}'], ['3', '{Tag01,AAA,BBB,CCC}']] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) send_keys(bp.operation_input(), 'AAA,BBB ,CCC') click(bp.operation_apply()) # Check apply button assert bp.operation_apply().is_enabled( ) is False, 'Apply button is enabled' click(bp.sync_updates_button()) # Check updated data in DB wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_tags_modified', True), 'Unexpected tags data in DB')
def custom_setup(self, etsy_testcase): self.stop_all() self.set_etsy_testcase(etsy_testcase) run_sql('HIVE', 'listings_14', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) setup_rabbit() self.restart_all() lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) d = self.driver pg = MainPage(d) pg.get_main(self.base_url) pg.select_filter_tab('Active')
def test_sync_description(self): """ Tests that data is written to the database when [Sync Updates] is clicked """ expected_data = [['1', 'invisible gloves New Description']] d = self.driver select_listings_to_edit(d) bp = BulkPage(d) row = bp.listing_row('First something 1234 (1)') description = row.find_element_by_css_selector( 'div.body span.description') click(description) sleep(1) form = row.find_element_by_css_selector('div.body form > textarea') click(form) send_keys(form, ' New Description') click( d.find_element_by_css_selector('bulk-edit-dashboard-op-container')) sleep(1) click(bp.sync_updates_button()) wait_for_assert( expected_data, lambda: run_sql('HIVE', 'select_description_modified', True), 'Unexpected data in DB')
def get_shop_last_sync_time() -> arrow.Arrow: """ Returns last sync time of the shop under test :return: timestamp as an Arrow object """ data = run_sql('HIVE', 'select_shop_last_sync', True) return arrow.get(data[0][2])
def test_edit_single_category(self): """ Tests that a single category can be edited """ expected_listings_01 = [ 'First something 1234 (1)\nClothing\nMen\'s Clothing\nSocks\nChoose Category', 'Second something 1235 (2)\nClothing\nMen\'s Clothing\nSocks\nChoose Category', 'Third something LG-512a (3)\nClothing\nMen\'s Clothing\nPants' ] expected_data = [['1', '1761']] self.select_listings_to_edit() d = self.driver bp = BulkPage(d) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_01 # update category of the 1st listing row = bp.listing_row('First something 1234 (1)') bp.select_category(['Accessories', 'Costume Accessories', 'Costume Tails & Ears', 'Costume Ears'], row, True) click(bp.sync_updates_button()) wait_for_assert(expected_data, lambda: run_sql('HIVE', 'select_taxonomy_id_modified', True), 'Unexpected taxonomy ID in DB')
def test_etsy_shop_vacation(self): """ Test verifies that sync of a shop in vacation mode results in marking the shop as invalid and displaying proper message to user. Introduced in HIVE-966. """ expected_db_data_queue = [['1', 'syncShop', '2', 'aborted', '']] expected_db_shop_status = [[ 'GetvelaTest2', 'incomplete_shop_sync_in_vacation_mode', 't', '' ]] expected_vacation_mode_message = """Vacation Mode It appears that your shop is in or was was recently brought out of “Vacation Mode”. When a shop is in “Vacation Mode”, \ Etsy takes it offline, which prevents Vela (or any apps) from being able to connect to it Once you bring it back online, there is typically a 4 hour delay between the listings appearing on Etsy and then being \ reflected in Vela, but at that point everything should match up and you'll be free to edit. Hopefully this provides a little clarity, but if you have any questions, please feel free to reach out by clicking the \ blue chat icon (bottom right hand corner) or via email at [email protected]""" self.stop_all() self.set_etsy_testcase('listings_shop_vacation') run_sql('HIVE', 'listings_10', retry=2) self.restart_all() # check that sync task is aborted wait_for_assert(expected_db_data_queue, lambda: run_sql('HIVE', 'select_operations', True), 'syncShop task was not completed as expected', retries=30) # check that shop was marked invalid and why shop_status = run_sql('HIVE', 'select_shop_status', True) assert expected_db_shop_status == shop_status # check vacation mode message lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) mp = MainPage(self.driver) vacation_mode_message = mp.invalid_shop_text() assert expected_vacation_mode_message == vacation_mode_message
def setup_method(self, method): super().setup_method(method) self.stop_all() setup_rabbit() self.set_etsy_testcase('listings_02') run_sql('HIVE', 'listings_02', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all() lp = LoginPage(self.driver) lp.login(page=self.login_url_http) mp = MainPage(self.driver) mp.get_main(self.base_url) mp.select_filter_tab('Active') mp.select_listings_to_edit(checked_listings=LISTINGS_TO_CHECK) bp = BulkPage(self.driver) click(bp.edit_part('Section'))
def setup_method(self, method): super().setup_method(method) setup_rabbit() self.set_etsy_testcase('listings_16') self.stop_all() run_sql('HIVE', 'listings_16_changed', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all() self.db = HiveDatabase(HIVE_DATABASE_URL) lp = LoginPage(self.driver) lp.login(page=self.login_url_http) # Select both listings and go to bulk editor mp = MainPage(self.driver) mp.get_main(self.base_url) mp.select_filter_tab('Active') mp.select_listings_to_edit(checked_listings='ALL')
def test_auth_data_up_to_date(self): """ Test verifies that our auth test data were migrated (using script migrate-hivedb-data) with all migrations scripts for hive. Test compares contents of pgmigrations table for empty database and for all auth files. """ # get list of migrations from freshly set-up DB migrations = run_sql('AUTH', 'select_migrations', True) files = glob.glob(os.path.join(DB_DIR, 'auth_*.sql')) if not files: raise Exception('No sql file found') # check that all listings files contain the same migrations as freshly set-up DB for filename in files: auth_name = os.path.splitext(os.path.basename(filename))[0] run_sql('AUTH', auth_name) listings_migrations = run_sql('AUTH', 'select_migrations', True) assert migrations == listings_migrations,\ 'Test data ' + auth_name + ' file is not migrated properly'
def test_main_active_listing_data(self): """ Test verifies that all data of an active listing are displayed correctly on the main page """ expected_listings_texts = [ACTIVE_TITLE, '1', '$5.15', '1/1/18', 'Summer Sale'] run_sql('HIVE', 'listings_02', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) self.restart_all() lp = LoginPage(self.driver) lp.login(page=self.login_url_http) mp = MainPage(self.driver) mp.get_main(self.base_url) mp.select_filter_tab('Active') listing_texts = mp.listing_texts(ACTIVE_TITLE) assert listing_texts == expected_listings_texts
def test_login_record(self): """ Tests that the timestamp is recorder on login """ d = self.driver lpg = LoginPage(d) # first login lpg.login(page=self.login_url_http) today = arrow.utcnow().floor('day') # check DB db_data = run_sql('AUTH', 'select_login_time', True) print("db_data=", db_data) first_login_day = arrow.get(db_data[0][0]).to('utc').floor('day') assert first_login_day == today assert db_data[0][0] == db_data[0][1] # log in again self.tc.stop_browser() self.driver = self.tc.start_browser() d = self.driver d.get(self.base_url) sleep(2) lpg = LoginPage(d) lpg.login(page=self.login_url_http) today = arrow.utcnow().floor('day') # check DB db_data = run_sql('AUTH', 'select_login_time', True) print("db_data=", db_data) first_login_day = arrow.get(db_data[0][0]).to('utc').floor('day') last_login_day = arrow.get(db_data[0][1]).to('utc').floor('day') assert first_login_day == today assert last_login_day == today # first login timestamp != last login timestamp assert db_data[0][0] != db_data[0][1] # login count assert db_data[0][2] == '2'
def setup_method(self, method): super().setup_method(method) self.stop_all() run_sql('HIVE', 'listings_03', retry=2) run_sql('HIVE', 'update_shops_timestamp', retry=2) run_sql('AUTH', 'auth_01', retry=2) self.restart_all() self.driver.get(self.login_url_http)
def test_create_account(self, test_whitespaces): """ Tests that the user can create an account and log in with it """ d = self.driver cap = CreateAccountPage(d) self.stop_all() self.set_etsy_testcase('listings_09') run_sql('AUTH', 'auth_01', retry=2) self.restart_all() # go to create account page d.get(self.login_url_https + "createAccount") sleep(1) # create account send_keys(cap.firstname(), 'Test') send_keys(cap.lastname(), 'User') email_text = '*****@*****.**' if test_whitespaces == Whitespaces.yes: # the case when whitespaces are around email in input field email_text = ' ' + email_text + ' ' send_keys(cap.email(), email_text) send_keys(cap.password(), 'secret123') send_keys(cap.password2(), 'secret123') click(cap.submit_button()) # check DB db_data = run_sql('AUTH', 'select_test_user', True) assert db_data == [['Test', 'User']] # log in using the new account d.delete_all_cookies() lp = LoginPage(d) lp.login(user='******', password='******', page=self.login_url_http) mp = MainPage(d) assert mp.is_displayed(), 'Login failed, main page is not displayed'