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'
Exemple #2
0
    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_description_mixed_content(self):
        """ Tests that switching between descriptions does not cause listing-1 to contain description of listing-2
        """
        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')

        # save it
        click(
            d.find_element_by_css_selector('bulk-edit-dashboard-op-container'))
        sleep(1)

        # 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'

        # 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)
        form = row2.find_element_by_css_selector('div.body form > textarea')
        click(form)

        # click on the 1st description
        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'
        click(description)
        sleep(1)
        form = row.find_element_by_css_selector('div.body form > textarea')
        click(form)
        sleep(1)
        assert form.text == 'invisible gloves Test'
    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> &amp; > 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> &amp; > 1'
    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_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_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_delete_single_material(self):
        """ Tests that single material can be deleted
        """
        select_listings_to_edit(self.driver)
        d = self.driver
        bp = BulkPage(d)

        row = bp.listing_row('First something 1234 (1)')
        material_names = bp.material_names(row)
        assert material_names == ['wool']

        materials = bp.material_elements(row)
        close_icon = materials[0].find_element_by_css_selector('span.close')
        click(close_icon)
        sleep(1)

        material_names = bp.material_names(
            bp.listing_row('First something 1234 (1)'))
        assert material_names == []

        titles = bp.listing_rows_texts_sorted()
        assert titles[0] == "First something 1234 (1)\n13 remaining"
Exemple #10
0
    def test_delete_single_tag(self):
        """ Tests that single tag can be deleted
        """

        select_listings_to_edit(self.driver)
        d = self.driver
        bp = BulkPage(d)

        row = bp.listing_row('First something 1234 (1)')
        tag_names = bp.tag_names(row)
        assert tag_names == ['Tag01']

        tags = bp.tag_elements(row)
        close_icon = tags[0].find_element_by_css_selector('span.close')
        click(close_icon)
        sleep(2)

        tag_names = bp.tag_names(row)
        assert tag_names == []

        titles = bp.listing_rows_texts_sorted()
        assert titles[0] == "First something 1234 (1)\n13 remaining"
Exemple #11
0
    def test_bulk_photo(self):
        """ Tests photos can be added, replaced, deleted
        """

        d = self.driver
        bp = BulkPage(d)

        # add bulk photos
        bp.select_photo(0, full_path('onion.jpg'))
        bp.select_photo(1, full_path('bunny.jpeg'))
        click(bp.operation_apply())

        apply_class = bp.operation_apply().get_attribute('class')
        assert 'inactive' in apply_class.split(' ')

        # add individual photos
        row = bp.listing_row('Second something 1235 (2)')
        photos = bp.row_photo_elements(row)
        bp.select_image(photos[2], full_path('jmeter.png'))
        bp.select_image(photos[3], full_path('ario.png'))

        # replace images
        bp.select_operation('Replace')
        bp.select_photo(3, full_path('mail.png'))
        click(bp.operation_apply())

        apply_class = bp.operation_apply().get_attribute('class')
        assert 'inactive' in apply_class.split(' ')

        # delete images
        bp.select_operation('Delete')
        photos = bp.bulk_photo_elements()
        click(photos[2])
        click(bp.operation_apply())

        apply_class = bp.operation_apply().get_attribute('class')
        assert 'inactive' in apply_class.split(' ')
Exemple #12
0
    def test_wholesale_import(self):
        """ Test verifies import and UI appearance 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.
        """

        expected_wholesale_inventory_listing_text = 'Two\n' + CANNOT_EDIT_INVENTORY_TEXT
        expected_wholesale_attributes_listing_text = {
            'Occasion': 'Two\n' + CANNOT_EDIT_OCCASION_TEXT,
            'Holiday': 'Two\n' + CANNOT_EDIT_HOLIDAY_TEXT,
        }

        expected_retail_listing_texts = {
            'Price': 'One\n$10.00',
            'Quantity': 'One\n1',
            'SKU': 'One',
            'Occasion': 'One\nAnniversary',
            'Holiday': 'One\nChoose Holiday'
        }

        self.set_etsy_testcase('listings_15')
        self.stop_all()
        run_sql('HIVE', 'listings_no_shop', retry=2)
        self.restart_all()

        # Import shop with two listings
        lp = LoginPage(self.driver)
        lp.login(page=self.login_url_http)
        lp.go_to_etsy()

        vela.wait_for_shop_to_sync(expected_status='up_to_date')

        # Select both listings and go to bulk page
        mp = MainPage(self.driver)
        mp.get_main(self.base_url)
        mp.select_filter_tab('Active')

        mp.select_listings_to_edit(checked_listings='ALL')

        # In Variations editor, check error message on the non-retail listing
        bp = BulkPage(self.driver)
        click(bp.edit_part('Variations'))
        assert 'Choose Property' in bp.listing_row('One').text
        assert bp.listing_row(
            'Two').text == expected_wholesale_inventory_listing_text

        # In remaining Inventory editors, check error message on the non-retail listing
        for editor_name in ['Price', 'Quantity', 'SKU']:
            click(bp.edit_part(editor_name))
            assert bp.listing_row(
                'One').text == expected_retail_listing_texts[editor_name]
            assert bp.listing_row(
                'Two').text == expected_wholesale_inventory_listing_text

        # In Holiday, Occasion editors, check error message on the non-retail listing
        for editor_name in ['Occasion', 'Holiday']:
            click(bp.edit_part(editor_name))
            assert bp.listing_row(
                'One').text == expected_retail_listing_texts[editor_name]
            assert bp.listing_row(
                'Two'
            ).text == expected_wholesale_attributes_listing_text[editor_name]
Exemple #13
0
    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
Exemple #14
0
    def test_title_add_before_uncheck(self):
        """ Tests add before where a listing is unselected
        """

        expected_listings_1 = [
            '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'
        ]
        expected_listings_2 = [
            'Hello First something 1234 (1)\n110 characters remaining',
            'Hello Second something 1235 (2)\n109 characters 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()

        listing_row = bp.listing_row('Third something LG-512a (3)',
                                     bp.TITLE_ROW_SELECTOR)

        # Normal add before
        send_keys(input_field, 'Hello ')
        listings = bp.listing_rows_texts_sorted()
        assert listings == expected_listings_1

        # Uncheck Third row

        click(listing_row)
        sleep(2)
        row_class = listing_row.get_attribute('class')
        assert 'selected' not in row_class.split(' ')
        listings = bp.listing_rows_texts_sorted()
        assert listings == expected_listings_2

        # Check Third row
        click(listing_row)
        sleep(2)
        row_class = listing_row.get_attribute('class')
        assert 'selected' in row_class.split(' ')
        listings = bp.listing_rows_texts_sorted()
        assert listings == expected_listings_1

        # Uncheck Third row
        click(listing_row)
        sleep(2)
        row_class = listing_row.get_attribute('class')
        assert 'selected' not in row_class.split(' ')
        listings = bp.listing_rows_texts_sorted()
        assert listings == expected_listings_2

        # 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(' ')