def test_description_discard(self): """ Tests that the single description changes are not discarded when a user starts editing a new one """ select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) row = bp.listing_row('First something 1234 (1)') description = row.find_element_by_css_selector( 'div.body span.description') assert description.text == 'invisible gloves' click(description) sleep(1) form = row.find_element_by_css_selector('div.body form > textarea') click(form) send_keys(form, ' Test') # click on the second description row2 = bp.listing_row('Second something 1235 (2)') description2 = row2.find_element_by_css_selector( 'div.body span.description') click(description2) # check the 1st description is saved row = bp.listing_row('First something 1234 (1)') description = row.find_element_by_css_selector( 'div.body span.description') assert description.text == 'invisible gloves Test'
def select_listings_to_edit(driver, operation='Add Before'): mp = MainPage(driver) bp = BulkPage(driver) mp.select_listings_to_edit() click(bp.edit_part('Description')) bp.select_operation(operation)
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 test_single_description_required(self): """ Tests that single description cannot be changed to empty """ select_listings_to_edit(self.driver) d = self.driver 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) # delete description and check error message form = row.find_element_by_css_selector('div.body form > textarea') click(form) send_keys(form, BACKSPACE_KEYS * 4) sleep(1) error_text = bp.error_baloon_texts(row) assert error_text == ['Description is required'] # click away and check that description was not changed click( d.find_element_by_css_selector('bulk-edit-dashboard-op-container')) description_text = row.find_element_by_css_selector( 'div.body span.description').text assert description_text == 'invisible gloves'
def test_edit_single_description(self): """ Tests that single description can be edited, including special characters """ select_listings_to_edit(self.driver) d = self.driver mp = MainPage(d) bp = BulkPage(d) row = bp.listing_row('First something 1234 (1)') description = row.find_element_by_css_selector( 'div.body span.description') assert description.text == 'invisible gloves' click(description) sleep(1) form = row.find_element_by_css_selector('div.body form > textarea') click(form) send_keys(form, ' Hello<b> & > 1') click( d.find_element_by_css_selector('bulk-edit-dashboard-op-container')) sleep(1) description_text = row.find_element_by_css_selector( 'div.body span.description').text assert description_text == 'invisible gloves Hello<b> & > 1'
def select_listings_to_edit(driver, operation='Add'): mp = MainPage(driver) bp = BulkPage(driver) mp.select_listings_to_edit() click(bp.edit_part('Tags')) bp.select_operation(operation)
def select_listings_to_edit(request): """ select listings for bulk, - self.listings_to_select is on of: None -> use default ["listing1", "listin2"...] -> use this "ALL" -> select all - self.listing_status -> e.g. 'Draft' - choose `self.bulk_tab` """ self = request.node.parent.obj mp = MainPage(self.driver) bp = BulkPage(self.driver) try: listing_status = self.listing_status except AttributeError: listing_status = None try: listings_to_select = self.listings_to_select except AttributeError: listings_to_select = None try: bulk_tab = self.bulk_tab except AttributeError: bulk_tab = None mp.select_listings_to_edit(listings_to_select, status=listing_status) if bulk_tab: click(bp.edit_part(bulk_tab))
def test_bulk_edit_view_listings_checked(self): """ Tests that the bulk edit view shows the listings checked on all pages """ d = self.driver pg = MainPage(d) bp = BulkPage(d) pg.select_filter_tab('Active') sleep(1) # check all click(pg.listing_select_all_checkbox()) assert pg.edit_listings_button().text == 'Edit 102 Listings' # clck the Edit Listings click(pg.edit_listings_button()) sleep(1) # check the listings 1st page listing_rows = bp.listing_rows() assert len(listing_rows) == 25 for listing_row in listing_rows: row_class = listing_row.get_attribute('class') assert 'selected' in row_class.split(' ') click(bp.next_page_button()) sleep(2) # check the listings 2nd page listing_rows = bp.listing_rows() assert len(listing_rows) == 50 for listing_row in listing_rows: row_class = listing_row.get_attribute('class') assert 'selected' in row_class.split(' ')
def select_listings_to_edit(driver, holiday=None): mp = MainPage(driver) bp = BulkPage(driver) mp.select_listings_to_edit(checked_listings='ALL') click(bp.edit_part('Holiday')) if holiday is not None: bp.select_holiday(holiday)
def select_listings_to_edit(self, operation=None): mp = MainPage(self.driver) bp = BulkPage(self.driver) mp.select_listings_to_edit() click(bp.edit_part('Quantity')) if operation is not None: bp.select_operation(operation)
def select_listings_to_edit(driver, occasion=None): mp = MainPage(driver) bp = BulkPage(driver) mp.select_listings_to_edit(checked_listings='ALL') click(bp.edit_part('Occasion')) if occasion is not None: bp.select_occasion(occasion)
def setup_method(self, method): super().setup_method(method) lpg = LoginPage(self.driver) lpg.login(page=self.login_url_http) mp = MainPage(self.driver) bp = BulkPage(self.driver) mp.select_listings_to_edit() click(bp.edit_part('Photos'))
def test_create_tag_too_long(self): """ Tests that a tag cannot be longer than 20 characters """ select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) send_keys(bp.operation_input(), 'AAAAABBBBBCCCCCDDDDDE') err = bp.error_baloon() assert err == "Maximum length of tag is 20"
def test_bulk_category_variations_validation(self): """ Test verifies that error message is shown when attempting to change Category to incompatible with existing Variation property / scale on the listing, and that Category is not changed for such listing """ expected_categories = [ ['Jewelry', 'Brooches'], ['Jewelry', 'Brooches'], ['Clothing', 'Women\'s Clothing', 'Dresses'] ] category = ['Jewelry', 'Brooches'] bp = BulkPage(self.driver) # change to incompatible category (3rd listing) bp.select_category(category) row = bp.listing_row('Product #3 with two variations with quantity on both and pricing on both') # check that error is shown assert bp.error_baloon_texts(row) ==\ ['The selected category is not compatible with the variations of this listing'],\ 'Incorrect validation error message for listing #3' # Apply and check that category was set for 1st and 2nd listings, for 3rd it hasn't changed click(bp.operation_apply()) for i, row in enumerate(bp.listing_rows()): category_names = bp.category_names(row) assert category_names == expected_categories[i]
def test_title_replace(self): """ Tests title replace - basic test """ expected_listings_1 = [ 'Prvni something 1234 (1)\n116 characters remaining', 'Second something 1235 (2)\n115 characters remaining', 'Third something LG-512a (3)\n113 characters remaining' ] select_listings_to_edit(self.driver, 'Find & Replace') d = self.driver bp = BulkPage(d) input_find_field = bp.operation_input_find() input_replace_field = bp.operation_input_replace() # Normal Replace send_keys(input_find_field, 'First') send_keys(input_replace_field, 'Prvni') listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_1 # Apply (client only) click(bp.operation_apply()) sleep(1) listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_1 apply_class = bp.operation_apply().get_attribute('class') assert 'inactive' in apply_class.split(' ')
def test_create_category(self): """ Tests that a category can be created in bulk edit """ 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_listings_02 = [ 'First something 1234 (1)\nAccessories\nCostume Accessories\nCostume Tails & Ears\nCostume Ears', 'Second something 1235 (2)\nAccessories\nCostume Accessories\nCostume Tails & Ears\nCostume Ears', 'Third something LG-512a (3)\nAccessories\nCostume Accessories\nCostume Tails & Ears\nCostume Ears' ] self.select_listings_to_edit() d = self.driver bp = BulkPage(d) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_01 bp.select_category(['Accessories', 'Costume Accessories', 'Costume Tails & Ears', 'Costume Ears']) # Apply changes click(bp.operation_apply()) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_02 apply_class = bp.operation_apply().get_attribute('class') assert 'inactive' in apply_class.split(' ')
def test_create_tag_special_chars(self): """ Tests that a tag can be created in bulk edit with czech chars, but not special chars """ expected_tags = [ ['Tag01', 'žvýkačky'], ['Tag01', 'žvýkačky'], ['Tag01', 'žvýkačky'], ] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) send_keys(bp.operation_input(), 'žvýkačky') click(bp.operation_apply()) apply_class = bp.operation_apply().get_attribute('class') assert 'inactive' in apply_class.split(' ') tag_names = bp.tag_names() assert tag_names == expected_tags send_keys(bp.operation_input(), 'me@site') err = bp.error_baloon() assert err == "Tag can only include spaces, letters, hyphens, and numbers"
def test_inline_section_remove(self): """ Tests removing section from a single listing """ expected_section_names = ['Summer Sale', 'Choose Section'] expected_api_calls = [{ 'PUT': '/v2/listings/100002?shop_section_id=0', 'body': { 'listing_id': 100002, 'state': 'active' } }] bp = BulkPage(self.driver) bp.select_single_section('Second something 1235', 'None') # Check listings assert bp.section_names() == expected_section_names # Check that sync button is enabled after clicking on Apply wait_for_web_assert(True, bp.sync_updates_button().is_enabled, 'Sync button is not enabled') # Sync changes click(bp.sync_updates_button()) # Check that sync button is disabled after clicking on Sync wait_for_web_assert(False, bp.sync_updates_button().is_enabled, 'Sync button is not disabled') # Check API calls to Etsy emulator - section should be set to None on one listing check_etsy_emulator_requests(expected_api_calls)
def test_inline_occasion_delete(self): """ Tests deleting occasion from a listing using inline edit """ self.custom_setup('listings_delete_occasion') expected_listings = [ 'Four\nThe category of this listing does not support occasion', 'One\nChoose Occasion', 'Three\nChoose Occasion', 'Two\nChoose Occasion' ] expected_occasion_db = [] expected_api_calls = [{ 'DELETE': '/v2/listings/100001/attributes/46803063641', 'body': {} }] select_listings_to_edit(self.driver) bp = BulkPage(self.driver) # Delete occasion from listing bp.select_single_occasion('One', 'None') # Check listings actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings # Check that sync button is enabled and blue dot is displayed after clicking on Apply wait_for_web_assert(True, bp.sync_updates_button().is_enabled, 'Sync button is not enabled') assert bp.is_part_modified( 'Occasion') is True, 'Blue dot didn\'t show up' # Sync changes click(bp.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, bp.sync_updates_button().is_enabled, 'Sync button is not disabled') assert bp.is_part_modified( 'Occasion') is False, 'Blue dot is still shown' # Check Etsy requests and occasion data in DB after resync check_etsy_emulator_requests(expected_api_calls) check_db_state(expected_occasion_db)
def select_single(self, row, position, new_value): d = self.driver bp = BulkPage(d) element = bp.category_elements(row)[position] click(element) sleep(2) category_found = False for item in element.find_elements_by_css_selector('div.bulk-edit-dropdown ul li'): if item.text == new_value: d.execute_script("arguments[0].scrollIntoView(true);", item); click(item) sleep(1) category_found = True break if not category_found: raise Exception("Error: select_single: " + new_value + " not found")
def test_bulk_holiday_delete(self): """ Tests deleting holiday from listings using bulk """ self.custom_setup('listings_delete_holiday_bulk') expected_listings = [ 'Four\nThe category of this listing does not support holiday', 'One\nChoose Holiday', 'Three\nChoose Holiday', 'Two\nChoose Holiday' ] expected_holiday_db = [] expected_api_calls = [{ 'DELETE': '/v2/listings/100002/attributes/46803063659', 'body': {} }, { 'DELETE': '/v2/listings/100003/attributes/46803063659', 'body': {} }] # Delete holiday from listings using bulk select_listings_to_edit(self.driver, 'None') bp = BulkPage(self.driver) # Apply changes and check listings click(bp.operation_apply()) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings # Check that sync button is enabled and blue dot is displayed after clicking on Apply wait_for_web_assert(True, bp.sync_updates_button().is_enabled, 'Sync button is not enabled') assert bp.is_part_modified( 'Holiday') is True, 'Blue dot didn\'t show up' # Sync changes click(bp.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, bp.sync_updates_button().is_enabled, 'Sync button is not disabled') assert bp.is_part_modified( 'Holiday') is False, 'Blue dot is still shown' # Check Etsy requests and holiday data in DB after resync check_etsy_emulator_requests(expected_api_calls) check_db_state(expected_holiday_db)
def test_bulk_holiday_set(self): """ Tests setting/changing holiday using bulk on listings """ self.custom_setup('listings_push_attributes') expected_listings = [ 'Four\nThe category of this listing does not support holiday', 'One\nChristmas', 'Three\nChristmas', 'Two\nChristmas' ] expected_api_calls = [{ 'PUT': '/v2/listings/100001/attributes/46803063659?value_ids=35', 'body': {} }, { 'PUT': '/v2/listings/100002/attributes/46803063659?value_ids=35', 'body': {} }, { 'PUT': '/v2/listings/100003/attributes/46803063659?value_ids=35', 'body': {} }] # Set/change holiday using bulk select_listings_to_edit(self.driver, 'Christmas') bp = BulkPage(self.driver) # Apply changes and check listings click(bp.operation_apply()) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings # Check that sync button is enabled and blue dot is displayed after clicking on Apply wait_for_web_assert(True, bp.sync_updates_button().is_enabled, 'Sync button is not enabled') assert bp.is_part_modified( 'Holiday') is True, 'Blue dot didn\'t show up' # Sync changes click(bp.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, bp.sync_updates_button().is_enabled, 'Sync button is not disabled') assert bp.is_part_modified( 'Holiday') is False, 'Blue dot is still shown' # Check holiday data in DB and Etsy requests check_etsy_emulator_requests(expected_api_calls)
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_title_add_before_length(self): """ Tests add before where length limit is exceeded """ long_text = 'Looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong' expected_listings_1 = [ long_text + 'First something 1234 (1)\n2 characters remaining', long_text + 'Second something 1235 (2)\n1 character remaining', long_text + 'Third something LG-512a (3)\n1 character over limit' ] expected_listings_2 = [ long_text + 'First something 1234 (1)\n2 characters remaining', long_text + 'Second something 1235 (2)\n1 character remaining', 'Third something LG-512a (3)\n113 characters remaining' ] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) input_field = bp.operation_input() # Test long text send_keys(input_field, long_text) listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_1 # Apply (client only) click(bp.operation_apply()) sleep(1) listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_2 apply_class = bp.operation_apply().get_attribute('class') assert 'inactive' in apply_class.split(' ')
def test_title_delete(self): """ Tests tile delete basic """ expected_listings_1 = [ 'First something 1234 (1)\n122 characters remaining', 'Second something 1235 (2)\n115 characters remaining', 'Third something LG-512a (3)\n113 characters remaining' ] expected_listings_2 = [ 'Second something 1235 (2)\n115 characters remaining', 'Third something LG-512a (3)\n113 characters remaining', 'something 1234 (1)\n122 characters remaining' ] select_listings_to_edit(self.driver, 'Delete') d = self.driver bp = BulkPage(d) input_field = bp.operation_input() # Normal Delete send_keys(input_field, 'First ') listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_1 # Apply (client only) click(bp.operation_apply()) sleep(1) listings = bp.listing_rows_texts_sorted() assert listings == expected_listings_2 apply_class = bp.operation_apply().get_attribute('class') assert 'inactive' in apply_class.split(' ')
def test_title_add_before_starting_chars(self): """ Tests that add before title starts with valid chars """ expected_listings_1 = [ '123First something 1234 (1)\n113 characters remaining', '123Second something 1235 (2)\n112 characters remaining', '123Third something LG-512a (3)\n110 characters remaining' ] expected_listings_2 = [ '@ First something 1234 (1)\nMust begin with alphanumerical character', '@ Second something 1235 (2)\nMust begin with alphanumerical character', '@ Third something LG-512a (3)\nMust begin with alphanumerical character' ] expected_listings_3 = [ 'á First something 1234 (1)\n114 characters remaining', 'á Second something 1235 (2)\n113 characters remaining', 'á Third something LG-512a (3)\n111 characters remaining' ] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) input_field = bp.operation_input() # Test 123 prefix - OK send_keys(input_field, '123') listings = bp.listing_rows_texts_sorted() error_msg = bp.error_baloon() assert error_msg == '' assert listings == expected_listings_1 # Test @ prefix - show error, temp title does not contain it send_keys(input_field, BACKSPACE_KEYS) send_keys(input_field, '@ ') sleep(2) listings = bp.listing_rows_texts_sorted() error_msg = bp.error_baloon() assert error_msg == 'Must begin with alphanumerical character' assert listings == expected_listings_2 # Test á prefix - no error, temp title contains it send_keys(input_field, BACKSPACE_KEYS) send_keys(input_field, 'á ') listings = bp.listing_rows_texts_sorted() error_msg = bp.error_baloon() assert error_msg == '' assert listings == expected_listings_3
def test_create_material_multi_basic(self): """ Tests that multiple materials can be created in bulk edit """ expected_materials = [ ['cotton', 'AAA', 'BBB', 'CCC'], ['cotton', 'AAA', 'BBB', 'CCC'], ['wool', '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()) material_names = bp.material_names() assert material_names == expected_materials
def test_delete_material(self): """ Tests that materials can be deleted in bulk """ expected_materials = [ [], ['cotton'], ['cotton'], ] select_listings_to_edit(self.driver, 'Delete') d = self.driver bp = BulkPage(d) send_keys(bp.operation_input(), 'wool') click(bp.operation_apply()) material_names = bp.material_names() assert material_names == expected_materials
def test_title_add_before_correct(self): """ Tests that correct text can be added before """ expected_listings = [ 'hello First something 1234 (1)\n110 characters remaining', 'hello Second something 1235 (2)\n109 characters remaining', 'hello Third something LG-512a (3)\n107 characters remaining' ] select_listings_to_edit(self.driver) d = self.driver bp = BulkPage(d) input_field = bp.operation_input() send_keys(input_field, 'hello ') listings = bp.listing_rows_texts_sorted() assert listings == expected_listings
def test_bulk_section_add(self): """ Tests adding a new section and setting it to listings using bulk operation """ new_section_name = 'New section' expected_section_names = [new_section_name] * 2 expected_api_calls = [{ 'POST': '/v2/shops/14458117/sections?title=New%20section', 'body': {} }, { 'PUT': '/v2/listings/100001', 'body': { 'listing_id': 100001, 'shop_section_id': '66666666', 'state': 'active' } }, { 'PUT': '/v2/listings/100002', 'body': { 'listing_id': 100002, 'shop_section_id': '66666666', 'state': 'active' } }] bp = BulkPage(self.driver) bp.add_new_section(new_section_name) # Apply changes and check listings click(bp.operation_apply()) assert bp.section_names() == expected_section_names # Check that sync button is enabled after clicking on Apply wait_for_web_assert(True, bp.sync_updates_button().is_enabled, 'Sync button is not enabled') # Sync changes click(bp.sync_updates_button()) # Check that sync button is disabled after clicking on Sync wait_for_web_assert(False, bp.sync_updates_button().is_enabled, 'Sync button is not disabled') # Check API calls to Etsy emulator - new section should be created and two listings updated check_etsy_emulator_requests(expected_api_calls)