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 sync_changes(self, timeout_sec=5): click(self.sync_updates_button()) wait_for_web_assert(False, lambda: self.sync_updates_button().is_enabled(), 'Sync button is not disabled after sync', delay_sec=1, retries=timeout_sec)
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_inventory_sku_change_to(self): """ Tests Change to operation for SKU editor :return: """ expected_listings = [ 'Product #1 without variations\n550', 'Product #2 with one variation with pricing\nCHANGE', 'Product #3 with two variations with quantity on both and pricing on both\nCHANGE' ] # Change SKUs on 2nd and 3rd listing operation = 'Change To' bis = BulkPageInventorySku(self.driver, self.ts) bis.select_operation(operation) # unselect 1st bis.click_on_listings(['Product #1 without variations']) # enter new SKU send_keys(bis.sku_input(), 'CHANGE') # Apply and check results click(bis.operation_apply()) wait_for_web_assert(False, bis.operation_apply().is_enabled, 'Apply button is not disabled') assert bis.listing_rows_texts_sorted() == expected_listings
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 check_sync_button_and_dot(bp: BulkPageInventoryVariations, expected_sync_ready: bool): # Check the state of sync button and the blue dot wait_for_web_assert( expected_sync_ready, bp.sync_updates_button().is_enabled, 'Sync button is' + (' not' if expected_sync_ready else '') + ' disabled') assert bp.is_part_modified('Variations') is expected_sync_ready,\ 'Blue dot is' + (' not' if expected_sync_ready else '') + ' shown'
def test_wholesale_bulk_delete_occasion(self): """ Test verifies bulk delete of occasion of listings that have different value of the flag 'can_write_inventory' - Etsy returns false for this flag when a listing is not Retail listing. So far it is not possible to update inventory and attributes on such listings through API, therefore VELA doesn't allow to change it. Test also verifies that if 'can_write_inventory' is changed to false on Etsy, no occasion updates of the listing are sent to Etsy (HIVE-1553). """ expected_can_write_inventory = [ ('100001', True), ('100002', False), ('100003', False), ] retail_expected_value = 'Choose Occasion' expected_api_calls = [{ 'DELETE': '/v2/listings/100001/attributes/46803063641', 'body': {} }] # ---- Make changes in Occasion editor ---- bp = BulkPage(self.driver) click(bp.edit_part('Occasion')) bp.select_occasion('None') # Apply changes and check listings click(bp.operation_apply()) assert bp.listing_row('One').text == 'One\n' + retail_expected_value assert bp.listing_row( 'Two').text == 'Two\n' + CANNOT_EDIT_OCCASION_TEXT assert bp.listing_row( 'Three').text == 'Three\n' + retail_expected_value # 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 - only first listing should be updated check_etsy_emulator_requests(expected_api_calls) # Check can_write_inventory flags in DB - it was set to False on the listing 'Three' assert self.db.get_can_write_inventory( ) == expected_can_write_inventory
def test_inventory_update_single_price(self): """ Tests that single price can be updated """ expected_listings_02 = { 'Product #1 without variations': '$10.50', 'Product #2 with one variation with pricing': [('Beige', '$1.00'), ('Black', '$2.00'), ('Blue', '$3.00'), ('Silver', '$4.00'), ('White', '$5.00'), ('Yellow', '$6.00'), ('Custom color 1', '$7.00'), ('Custom color 2', '$8.00')], 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '$99.00'), ('XXS US Women\'s', 'Material 2', '$99.00'), ('XXS US Women\'s', 'Material 3', '$99.00'), ('One size (plus) US Women\'s', 'Material 1', '$99.00'), ('One size (plus) US Women\'s', 'Material 2', '$99.00'), ('One size (plus) US Women\'s', 'Material 3', '$99.00'), ('Custom size 1 US Women\'s', 'Material 1', '$99.00'), ('Custom size 1 US Women\'s', 'Material 2', '$99.00'), ('Custom size 1 US Women\'s', 'Material 3', '$99.00'), ] } bip = BulkPageInventoryPrice(self.driver, self.ts) actual_listings = bip.listing_details() self.check_listing_options(actual_listings, expected_listings_01) # unselect 1st bip.click_on_listings(['Product #1 without variations']) # unselect 2nd bip.click_on_listings(['Product #2 with one variation with pricing']) # perform individual (inline) change of listing #1 row = bip.listing_row('Product #1 without variations') assert bip.product_price_text(row) == '$500.00' bip.set_individual_price(row, '10.50') # perform bulk change of selected listings (only 3rd) bip.select_operation('Change To') input_field = bip.operation_input_dolars() send_keys(input_field, '99') # apply changes click(bip.operation_apply()) wait_for_web_assert(False, bip.operation_apply().is_enabled, 'Apply button is enabled') # check listings actual_listings = bip.listing_details() self.check_listing_options(actual_listings, expected_listings_02)
def test_inline_holiday_change(self): """ Tests setting/changing holiday on a listing using inline edit """ self.custom_setup('listings_push_attributes') expected_listings = [ 'Four\nThe category of this listing does not support holiday', 'One\nEaster', 'Three\nVeterans\' Day', 'Two\nFather\'s Day' ] expected_api_calls = [{ 'PUT': '/v2/listings/100001/attributes/46803063659?value_ids=37', 'body': {} }, { 'PUT': '/v2/listings/100002/attributes/46803063659?value_ids=38', 'body': {} }, { 'PUT': '/v2/listings/100003/attributes/46803063659?value_ids=49', 'body': {} }] select_listings_to_edit(self.driver) bp = BulkPage(self.driver) # set holiday bp.select_single_holiday('One', 'Easter') # change holiday bp.select_single_holiday('Two', 'Father\'s Day') bp.select_single_holiday('Three', 'Veterans\' Day') # 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( '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_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_inline_occasion_change(self): """ Tests setting/changing of occasion on listings using inline edit """ self.custom_setup('listings_push_attributes') expected_listings = [ 'Four\nThe category of this listing does not support occasion', 'One\nEngagement', 'Three\nChoose Occasion', 'Two\nWedding' ] expected_api_calls = [{ 'PUT': '/v2/listings/100001/attributes/46803063641?value_ids=22', 'body': {} }, { 'PUT': '/v2/listings/100002/attributes/46803063641?value_ids=32', 'body': {} }] select_listings_to_edit(self.driver) bp = BulkPage(self.driver) # Change occasion bp.select_single_occasion('One', 'Engagement') # Set occasion bp.select_single_occasion('Two', 'Wedding') # 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 occasion data in Etsy requests check_etsy_emulator_requests(expected_api_calls)
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_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 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)
def test_inline_add_photo_sync(self): """ Test adding a picture using inline edit and syncing it to Etsy """ # the last API call doesn't show actual picture data, because we don't have multipart support in emulator expected_api_calls = [ { 'DELETE': '/v2/listings/100001/images/1224764834', 'body': {} }, { 'POST': '/v2/listings/100001/images', 'body': { 'listing_id': '100001', 'listing_image_id': '1224764834', 'overwrite': '1', 'rank': '1' } }, { 'POST': '/v2/listings/100001/images', 'body': { 'listing_id': '100001', 'overwrite': '1', 'rank': '2' } } ] bp = BulkPage(self.driver) # Add a photo to a listing bp.select_single_photo('One', 1, full_path('onion.jpg')) # 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('Photos') 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('Photos') is False, 'Blue dot is still shown' # Wait for shop to sync and check requests made to Etsy vela.wait_for_shop_to_sync(expected_status='up_to_date') check_etsy_emulator_requests(expected_api_calls)
def test_bulk_section_change(self): """ Tests changing section on listings using bulk operation """ expected_section_names = ['On Sale'] * 2 expected_api_calls = [{ 'PUT': '/v2/listings/100001', 'body': { 'listing_id': 100001, 'shop_section_id': '15183328', 'state': 'active' } }, { 'PUT': '/v2/listings/100002', 'body': { 'listing_id': 100002, 'shop_section_id': '15183328', 'state': 'active' } }] bp = BulkPage(self.driver) bp.select_section('On Sale') # 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 - section should be changed on two listings check_etsy_emulator_requests(expected_api_calls)
def test_bulk_occasion_validation(self): """ Tests that occasion can't be set at all or changed on certain categories that don't permit it """ expected_listings_01 = [ 'Four\nThe category of this listing does not support occasion', 'One\nAnniversary', 'Three\nChoose Occasion', 'Two\nChoose Occasion' ] expected_listings_02 = [ 'Four\nThe category of this listing does not support occasion', 'One\nGrief & Mourning', 'Three\nChoose Occasion\nOccasion cannot be changed due to category', 'Two\nChoose Occasion\nOccasion cannot be changed due to category' ] expected_listings_03 = [ 'Four\nThe category of this listing does not support occasion', 'One\nGrief & Mourning', 'Three\nChoose Occasion', 'Two\nChoose Occasion' ] bp = BulkPage(self.driver) select_listings_to_edit(self.driver) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_01 # Change occasion using bulk bp.select_occasion('Grief & Mourning') actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_02 # Apply changes and check listings click(bp.operation_apply()) actual_listings = bp.listing_rows_texts_sorted() assert actual_listings == expected_listings_03 # Check apply button wait_for_web_assert(False, bp.operation_apply().is_enabled, 'Apply button is enabled')
def test_inventory_set_quantity_normal(self): """ Tests that a quantity can be set in bulk edit inventory """ expected_listings_02 = { 'Product #1 without variations': '36', 'Product #2 with one variation with pricing': '36', 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '36'), ('XXS US Women\'s', 'Material 2', '36'), ('XXS US Women\'s', 'Material 3', '36'), ('One size (plus) US Women\'s', 'Material 1', '36'), ('One size (plus) US Women\'s', 'Material 2', '36'), ('One size (plus) US Women\'s', 'Material 3', '36'), ('Custom size 1 US Women\'s', 'Material 1', '36'), ('Custom size 1 US Women\'s', 'Material 2', '36'), ('Custom size 1 US Women\'s', 'Material 3', '36'), ] } expected_listings_03 = { 'Product #1 without variations': '10', 'Product #2 with one variation with pricing': '6', 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '6'), ('XXS US Women\'s', 'Material 2', '6'), ('XXS US Women\'s', 'Material 3', '6'), ('One size (plus) US Women\'s', 'Material 1', '6'), ('One size (plus) US Women\'s', 'Material 2', '6'), ('One size (plus) US Women\'s', 'Material 3', '6'), ('Custom size 1 US Women\'s', 'Material 1', '6'), ('Custom size 1 US Women\'s', 'Material 2', '6'), ('Custom size 1 US Women\'s', 'Material 3', '6'), ] } biq = BulkPageInventoryQuantity(self.driver, self.ts) actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_01) operation = 'Change To' biq.select_operation(operation) input_field = biq.operation_input() send_keys(input_field, '36') # Apply changes click(biq.operation_apply()) actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_02) assert biq.operation_apply().is_enabled() is False, 'Apply button is enabled' # individual change row = biq.listing_row('Product #1 without variations') assert biq.product_quantity_text(row) == '36' biq.set_individual_quantity(row, '10') # bulk change biq.select_operation(operation) input_field = biq.operation_input() send_keys(input_field, '6') # Apply and check listings click(biq.operation_apply()) wait_for_web_assert(False, biq.operation_apply().is_enabled, 'Apply button is enabled') actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_03)
def test_inventory_decrease_quantity(self): """ Tests that a quantity can be decreased in bulk edit """ expected_listings_02 = { 'Product #1 without variations': '45', 'Product #2 with one variation with pricing': '11', 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '1'), ('XXS US Women\'s', 'Material 2', '2'), ('XXS US Women\'s', 'Material 3', '3'), ('One size (plus) US Women\'s', 'Material 1', '4'), ('One size (plus) US Women\'s', 'Material 2', '5'), ('One size (plus) US Women\'s', 'Material 3', '6'), ('Custom size 1 US Women\'s', 'Material 1', '7'), ('Custom size 1 US Women\'s', 'Material 2', '8'), ('Custom size 1 US Women\'s', 'Material 3', '9') ] } expected_listings_03 = { 'Product #1 without variations': '10', 'Product #2 with one variation with pricing': '11', 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '99'), ('XXS US Women\'s', 'Material 2', '99'), ('XXS US Women\'s', 'Material 3', '99'), ('One size (plus) US Women\'s', 'Material 1', '99'), ('One size (plus) US Women\'s', 'Material 2', '99'), ('One size (plus) US Women\'s', 'Material 3', '99'), ('Custom size 1 US Women\'s', 'Material 1', '99'), ('Custom size 1 US Women\'s', 'Material 2', '99'), ('Custom size 1 US Women\'s', 'Material 3', '99'), ] } operation = 'Decrease By' biq = BulkPageInventoryQuantity(self.driver, self.ts) sleep(1) actual_listings = biq.listing_details() sleep(1) self.check_listing_options(actual_listings, expected_listings_01) # unselect 2nd biq.click_on_listings(['Product #2 with one variation with pricing']) biq.select_operation(operation) input_field = biq.operation_input() input_field.clear() send_keys(input_field, '5') # Apply changes # include negative scenario click(biq.operation_apply()) sleep(0.5) actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_02) assert biq.operation_apply().is_enabled() is False, 'Apply button is enabled' # Change individual quantity, make sure bulk still works row = biq.listing_row('Product #1 without variations') assert biq.product_quantity_text(row) == '45' biq.set_individual_quantity(row, '10') # bulk operation = 'Change To' biq.select_operation(operation) input_field = biq.operation_input_dolars() send_keys(input_field, '99') click(biq.operation_apply()) wait_for_web_assert(False, biq.operation_apply().is_enabled, 'Apply button is enabled') actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_03)
def test_inventory_increase_quantity(self): """ Tests that a quantity can be increased in bulk edit Also test the results in DB and check requests made to Etsy emulator. """ self.set_etsy_testcase('listings_push_inventory') expected_listings_02 = { 'Product #1 without variations': '60', 'Product #2 with one variation with pricing': '21', 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '11'), ('XXS US Women\'s', 'Material 2', '12'), ('XXS US Women\'s', 'Material 3', '13'), ('One size (plus) US Women\'s', 'Material 1', '14'), ('One size (plus) US Women\'s', 'Material 2', '15'), ('One size (plus) US Women\'s', 'Material 3', '16'), ('Custom size 1 US Women\'s', 'Material 1', '17'), ('Custom size 1 US Women\'s', 'Material 2', '18'), ('Custom size 1 US Women\'s', 'Material 3', '19'), ] } expected_product_offerings = [ ['1', '500.00', '550', '60', 't', '', '', '', ''], ['2', '1.00', '111', '21', 't', 'Beige', '1', '', ''], ['2', '2.00', '111', '21', 't', 'Black', '2', '', ''], ['2', '3.00', '111', '21', 'f', 'Blue', '3', '', ''], ['2', '4.00', '111', '21', 'f', 'Silver', '4', '', ''], ['2', '5.00', '111', '21', 't', 'White', '5', '', ''], ['2', '6.00', '111', '21', 't', 'Yellow', '6', '', ''], ['2', '7.00', '111', '21', 't', 'Custom color 1', '7', '', ''], ['2', '8.00', '111', '21', 't', 'Custom color 2', '8', '', ''], ['3', '10.00', '222', '11', 't', 'XXS', '1', 'Material 1', '1'], ['3', '20.00', '222', '12', 't', 'XXS', '1', 'Material 2', '2'], ['3', '30.00', '222', '13', 't', 'XXS', '1', 'Material 3', '3'], ['3', '40.00', '222', '14', 't', 'One size (plus)', '2', 'Material 1', '1'], ['3', '50.00', '222', '15', 'f', 'One size (plus)', '2', 'Material 2', '2'], ['3', '60.00', '222', '16', 't', 'One size (plus)', '2', 'Material 3', '3'], ['3', '70.00', '222', '17', 't', 'Custom size 1', '3', 'Material 1', '1'], ['3', '80.00', '222', '18', 't', 'Custom size 1', '3', 'Material 2', '2'], ['3', '90.00', '222', '19', 't', 'Custom size 1', '3', 'Material 3', '3'] ] from data.test_inventory_increase_quantity_expected_data import expected_api_calls operation = 'Increase By' biq = BulkPageInventoryQuantity(self.driver, self.ts) actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_01) # select operation and enter price difference biq.select_operation(operation) input_field = biq.quantity_input() send_keys(input_field, '10') # Apply changes assert biq.operation_apply().is_enabled() is True, 'Apply button is not enabled' click(biq.operation_apply()) # Check listings that changes were applied actual_listings = biq.listing_details() self.check_listing_options(actual_listings, expected_listings_02) assert biq.operation_apply().is_enabled() is False, 'Apply button is enabled' # Check that sync button is enabled and blue dot is displayed after clicking on Apply wait_for_web_assert(True, biq.sync_updates_button().is_enabled, 'Sync button is not enabled') assert biq.is_part_modified('Quantity') is True, 'Blue dot didn\'t show up' # Sync changes click(biq.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, biq.sync_updates_button().is_enabled, 'Sync button is not disabled') assert biq.is_part_modified('Quantity') is False, 'Blue dot is still shown' # --- Check state of data in DB and requests to Etsy emulator check_db_state(expected_product_offerings, DB_INITIAL_VARIATION_PROPERTIES, DB_INITIAL_VARIATION_OPTIONS) check_etsy_emulator_requests(expected_api_calls)
def test_inventory_decrease_price_percent(self): """ Tests that a price can be decreased by % in bulk edit Also test the results in DB and check requests made to Etsy emulator. """ self.set_etsy_testcase('listings_push_inventory') expected_listings_02 = { 'Product #1 without variations': '$250.00', 'Product #2 with one variation with pricing': [('Beige', '$0.50'), ('Black', '$1.00'), ('Blue', '$1.50'), ('Silver', '$2.00'), ('White', '$2.50'), ('Yellow', '$3.00'), ('Custom color 1', '$3.50'), ('Custom color 2', '$4.00')], 'Product #3 with two variations with quantity on both and pricing on both': [ ('XXS US Women\'s', 'Material 1', '$5.00'), ('XXS US Women\'s', 'Material 2', '$10.00'), ('XXS US Women\'s', 'Material 3', '$15.00'), ('One size (plus) US Women\'s', 'Material 1', '$20.00'), ('One size (plus) US Women\'s', 'Material 2', '$25.00'), ('One size (plus) US Women\'s', 'Material 3', '$30.00'), ('Custom size 1 US Women\'s', 'Material 1', '$35.00'), ('Custom size 1 US Women\'s', 'Material 2', '$40.00'), ('Custom size 1 US Women\'s', 'Material 3', '$45.00'), ] } expected_product_offerings = [ ['1', '250.00', '550', '50', 't', '', '', '', ''], ['2', '0.50', '111', '11', 't', 'Beige', '1', '', ''], ['2', '1.00', '111', '11', 't', 'Black', '2', '', ''], ['2', '1.50', '111', '11', 'f', 'Blue', '3', '', ''], ['2', '2.00', '111', '11', 'f', 'Silver', '4', '', ''], ['2', '2.50', '111', '11', 't', 'White', '5', '', ''], ['2', '3.00', '111', '11', 't', 'Yellow', '6', '', ''], ['2', '3.50', '111', '11', 't', 'Custom color 1', '7', '', ''], ['2', '4.00', '111', '11', 't', 'Custom color 2', '8', '', ''], ['3', '5.00', '222', '1', 't', 'XXS', '1', 'Material 1', '1'], ['3', '10.00', '222', '2', 't', 'XXS', '1', 'Material 2', '2'], ['3', '15.00', '222', '3', 't', 'XXS', '1', 'Material 3', '3'], [ '3', '20.00', '222', '4', 't', 'One size (plus)', '2', 'Material 1', '1' ], [ '3', '25.00', '222', '5', 'f', 'One size (plus)', '2', 'Material 2', '2' ], [ '3', '30.00', '222', '6', 't', 'One size (plus)', '2', 'Material 3', '3' ], [ '3', '35.00', '222', '7', 't', 'Custom size 1', '3', 'Material 1', '1' ], [ '3', '40.00', '222', '8', 't', 'Custom size 1', '3', 'Material 2', '2' ], [ '3', '45.00', '222', '9', 't', 'Custom size 1', '3', 'Material 3', '3' ] ] from data.test_inventory_price_decrease_percent_expected_data import expected_api_calls operation = 'Decrease By' bip = BulkPageInventoryPrice(self.driver, self.ts) actual_listings = bip.listing_details() self.check_listing_options(actual_listings, expected_listings_01) # use % bip.select_operation(operation) click(bip.operation_switch_percent()) input_field = bip.operation_input_dolars() send_keys(input_field, '50') # Apply changes and check Apply button after that click(bip.operation_apply()) actual_listings = bip.listing_details() self.check_listing_options(actual_listings, expected_listings_02) assert bip.operation_apply().is_enabled( ) is False, 'Apply button is enabled' # Check that sync button is enabled and blue dot is displayed after clicking on Apply wait_for_web_assert(True, bip.sync_updates_button().is_enabled, 'Sync button is not enabled') assert bip.is_part_modified( 'Price') is True, 'Blue dot didn\'t show up' # Sync changes click(bip.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, bip.sync_updates_button().is_enabled, 'Sync button is not disabled') assert bip.is_part_modified( 'Price') is False, 'Blue dot is still shown' # --- Check state of data in DB and requests to Etsy emulator check_db_state(expected_product_offerings, DB_INITIAL_VARIATION_PROPERTIES, DB_INITIAL_VARIATION_OPTIONS) check_etsy_emulator_requests(expected_api_calls)
def test_wholesale_bulk_change_inventory(self): """ Test verifies bulk changes of inventory of listings that have different value of the flag 'can_write_inventory' - Etsy returns false for this flag when a listing is not Retail listing. So far it is not possible to update inventory and attributes on such listings through API, therefore VELA doesn't allow to change it. Test also verifies that if 'can_write_inventory' is changed to false on Etsy, no inventory updates of the listing are sent to Etsy (HIVE-1553). """ api_products_unpacked1 = [{ 'offerings': [{ 'is_enabled': 1, 'price': 33.33, 'quantity': 21 }], 'property_values': [{ 'property_id': 500, 'property_name': 'Finish', 'scale_id': None, 'value': 'smooth', 'value_id': None }], 'sku': 'NEW SKU' }] expected_api_calls = [{ 'PUT': '/v2/listings/100001/inventory?price_on_property=&quantity_on_property=&sku_on_property=', 'body': { '_products_unpacked': api_products_unpacked1, 'listing_id': 100001 } }] expected_can_write_inventory = [ ('100001', True), ('100002', False), ('100003', False), ] bp = BulkPage(self.driver) # ---- Make changes in Variations editor ---- click(bp.edit_part('Variations')) category = ['Accessories'] bpiv = BulkPageInventoryVariations(self.driver, self.ts) # Select category in bulk edit area bpiv.select_category(category) # Set first variation property and its option bulk_row = bpiv.bulk_edit_row bpiv.set_property(bulk_row, 0, 'Finish') bpiv.add_custom_option(bulk_row, 0, 'smooth') # Apply changes and check results in UI click(bpiv.operation_apply()) assert 'smooth' in bpiv.listing_row('One').text assert bpiv.listing_row( 'Two').text == 'Two\n' + CANNOT_EDIT_INVENTORY_TEXT assert 'smooth' in bpiv.listing_row('Three').text wait_for_web_assert(True, lambda: bpiv.is_part_modified('Variations'), 'Blue dot didn\'t show up for Variations editor') # ---- Make changes in Price, Quantity, SKU editors ---- retail_values = {'Price': '33.33', 'Quantity': '21', 'SKU': 'NEW SKU'} retail_expected_values = { 'Price': '$33.33', 'Quantity': '21', 'SKU': 'NEW SKU' } for editor_name in ['Price', 'Quantity', 'SKU']: # Switch to particular inventory editor, choose bulk operation and set the value for it click(bpiv.edit_part(editor_name)) operation = 'Change To' bp.select_operation(operation) input_field = bp.operation_input() send_keys(input_field, retail_values[editor_name]) # Apply changes and check results in UI click(bp.operation_apply()) wait_for_web_assert( True, lambda: bp.is_part_modified(editor_name), 'Blue dot didn\'t show up for %s editor' % editor_name) assert bp.listing_row( 'One').text == 'One\n' + retail_expected_values[editor_name] assert bp.listing_row( 'Two').text == 'Two\n' + CANNOT_EDIT_INVENTORY_TEXT assert bp.listing_row( 'Three' ).text == 'Three\n' + retail_expected_values[editor_name] # 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') # Check API calls to Etsy emulator - only first listing should be updated check_etsy_emulator_requests(expected_api_calls) # Check can_write_inventory flags in DB - it was set to False on the listing 'Three' assert self.db.get_can_write_inventory( ) == expected_can_write_inventory
def test_inventory_sku_delete_and_replace(self): self.set_etsy_testcase('listings_push_inventory') expected_listings_02 = [ 'Product #1 without variations\n0022550', 'Product #2 with one variation with pricing\n0022111', 'Product #3 with two variations with quantity on both and pricing on both\n0022222' ] expected_listings_03 = [ 'Product #1 without variations\n00550', 'Product #2 with one variation with pricing\n00111', 'Product #3 with two variations with quantity on both and pricing on both\n002' ] expected_listings_04 = [ 'Product #1 without variations\nLOLO55LO', 'Product #2 with one variation with pricing\nLOLO111', 'Product #3 with two variations with quantity on both and pricing on both\nLOLO2' ] # expected at the end of the test expected_product_offerings = [ ['1', '500.00', 'LOLO55LO', '50', 't', '', '', '', ''], ['2', '1.00', 'LOLO111', '11', 't', 'Beige', '1', '', ''], ['2', '2.00', 'LOLO111', '11', 't', 'Black', '2', '', ''], ['2', '3.00', 'LOLO111', '11', 'f', 'Blue', '3', '', ''], ['2', '4.00', 'LOLO111', '11', 'f', 'Silver', '4', '', ''], ['2', '5.00', 'LOLO111', '11', 't', 'White', '5', '', ''], ['2', '6.00', 'LOLO111', '11', 't', 'Yellow', '6', '', ''], ['2', '7.00', 'LOLO111', '11', 't', 'Custom color 1', '7', '', ''], ['2', '8.00', 'LOLO111', '11', 't', 'Custom color 2', '8', '', ''], ['3', '10.00', 'LOLO2', '1', 't', 'XXS', '1', 'Material 1', '1'], ['3', '20.00', 'LOLO2', '2', 't', 'XXS', '1', 'Material 2', '2'], ['3', '30.00', 'LOLO2', '3', 't', 'XXS', '1', 'Material 3', '3'], ['3', '40.00', 'LOLO2', '4', 't', 'One size (plus)', '2', 'Material 1', '1'], ['3', '50.00', 'LOLO2', '5', 'f', 'One size (plus)', '2', 'Material 2', '2'], ['3', '60.00', 'LOLO2', '6', 't', 'One size (plus)', '2', 'Material 3', '3'], ['3', '70.00', 'LOLO2', '7', 't', 'Custom size 1', '3', 'Material 1', '1'], ['3', '80.00', 'LOLO2', '8', 't', 'Custom size 1', '3', 'Material 2', '2'], ['3', '90.00', 'LOLO2', '9', 't', 'Custom size 1', '3', 'Material 3', '3'] ] from data.test_inventory_sku_delete_and_replace_expected_data import expected_api_calls operation = 'Delete' bis = BulkPageInventorySku(self.driver, self.ts) assert expected_listings_01 == bis.listing_rows_texts_sorted() # this is shortcut how to add 0022 before every listings sku. Controls of corrections are in another Test send_keys(bis.sku_input(), '0022') click(bis.operation_apply()) assert expected_listings_02 == bis.listing_rows_texts_sorted() # work with new data bis.select_operation(operation) send_keys(bis.sku_input(), '22') # Apply changes click(bis.operation_apply()) assert expected_listings_03 == bis.listing_rows_texts_sorted() assert bis.is_part_modified('SKU') is True, 'Blue dot should be visible yet' assert bis.sync_updates_button().is_enabled() is True, 'Sync button should be enabled' assert bis.operation_apply().is_enabled() is False, 'Apply button is enabled' operation = 'Find & Replace' bis.select_operation(operation) bis.find_n_replace('0', 'LO') # Apply changes click(bis.operation_apply()) assert expected_listings_04 == bis.listing_rows_texts_sorted() assert bis.is_part_modified('SKU') is True, 'Blue dot should be visible yet' assert bis.sync_updates_button().is_enabled() is True, 'Sync button should be enabled' assert bis.operation_apply().is_enabled() is False, 'Apply button is enabled' # Sync changes click(bis.sync_updates_button()) # Check that sync button is disabled and blue dot is not displayed after clicking on Sync wait_for_web_assert(False, bis.sync_updates_button().is_enabled, 'Sync button is not disabled') assert bis.is_part_modified('SKU') is False, 'Blue dot is still shown' # --- Check state of data in DB and requests to Etsy emulator check_db_state(expected_product_offerings, DB_INITIAL_VARIATION_PROPERTIES, DB_INITIAL_VARIATION_OPTIONS) check_etsy_emulator_requests(expected_api_calls)