Skip to content

Commit

Permalink
#781 #772 #771 #696 disable huckster and implement google ecommerce t…
Browse files Browse the repository at this point in the history
…est (#782)

* Drop huckster

* Move YandexMetrict test class to test_js_analytics

* Implement test_google_ecommerce_purchase

* Review fixes
  • Loading branch information
ArtemijRodionov authored Mar 20, 2019
1 parent 9c3edaf commit 62f3cc9
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 224 deletions.
34 changes: 33 additions & 1 deletion shopelectro/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support import expected_conditions as EC, ui

from shopelectro.selenium import SiteDriver

Expand Down Expand Up @@ -42,6 +42,31 @@ def context_click(browser, element):
ActionChains(browser).context_click(element).perform()


def make_backcall(browser):
"""Trigger backcall modal. Fill it and submit."""
wait = ui.WebDriverWait(browser, 60)
browser.find_element_by_class_name('js-backcall-order').click()
wait.until(EC.visibility_of_element_located(
(By.ID, 'back-call-modal-label')
))
browser.find_element_by_id('back-call-phone').send_keys('2222222222')
browser.find_element_by_xpath(
'//*[@id="back-call-time"]/option[3]').click()
browser.find_element_by_class_name('js-send-backcall').click()
wait.until(EC.visibility_of_element_located(
(By.CLASS_NAME, 'js-backcall-success')
))


def show_cart_dropdown(browser):
wait = ui.WebDriverWait(browser, 60)
cart_parent = browser.find_element_by_class_name('basket-parent')
hover(browser, cart_parent)
wait.until(EC.visibility_of_element_located(
(By.CLASS_NAME, 'js-cart-wrapper')
))


class SeleniumTestCase(LiveServerTestCase):
"""Common superclass for running selenium-based tests."""

Expand Down Expand Up @@ -72,6 +97,13 @@ def setUpClass(cls):
def wait(self):
return self.browser.wait

def wait_page_loading(self):
ui.WebDriverWait(self.browser, 60).until(
EC.visibility_of_element_located(
(By.CLASS_NAME, 'content')
)
)

@classmethod
def tearDownClass(cls):
"""Close selenium session."""
Expand Down
193 changes: 188 additions & 5 deletions shopelectro/tests/tests_js_analytics.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import unittest

from django.test import override_settings, tag
from django.urls import reverse
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

from shopelectro import selenium
from shopelectro.tests import helpers
from shopelectro.models import CategoryPage, Order
from shopelectro.models import Category, CategoryPage, Order, Product

from pages.models import CustomPage


@tag('slow')
Expand All @@ -29,8 +36,184 @@ def test_google_ecommerce_purchase(self):
success_page.wait_loaded()
self.assertTrue(success_page.is_success())

order = Order.objects.order_by('-created').first() # Ignore PyFlakesBear
reached = self.browser.execute_script('return gaObject.results;') # Ignore PyFlakesBear
order = Order.objects.order_by('-created').first()
order_positions = order.positions.all()
reached = self.browser.execute_script('return gaObject.results;')
require, transaction, *positions, send = reached

self.assertEqual(require, ['require', 'ecommerce'])
self.assertEqual(
transaction,
['ecommerce:addTransaction', {
'id': order.fake_order_number, 'revenue': order.revenue,
}],
)
for pos, order_pos in zip(positions, order_positions):
self.assertEqual(
pos,
['ecommerce:addItem', {
'name': order_pos.name,
'price': order_pos.price,
'quantity': order_pos.quantity,
}],
)
self.assertEqual(send, ['ecommerce:send', None])

# @todo #771:60m Test Yandex eCommerce


@tag('slow')
@helpers.disable_celery
@override_settings(DEBUG=True, INTERNAL_IPS=tuple())
class YandexMetrika(helpers.SeleniumTestCase):

CART_LOCATOR = (By.CLASS_NAME, 'js-go-to-cart')

def setUp(self):
product_vendor_code = Product.objects.first().vendor_code
self.product_path = reverse('product', args=(product_vendor_code,))
self.category_path = reverse(
'category',
args=(Category.objects.first().page.slug,),
)
self.order_page_url = reverse(CustomPage.ROUTE, args=('order',))
self.browser.get('/')
self.wait_page_loading()

@property
def reached_goals(self):
"""Return yaCounter.goals array after triggering goal."""
return self.browser.execute_script('return yaCounter20644114.goals;')

def prevent_default(self, event, selector):
"""Use event.preventDefault() to prevent web page reloading."""
self.browser.execute_script(
f'var target = document.querySelector("{selector}");'
'console.log(target);'
f'target.on{event} = function(event) {{'
'event.preventDefault();'
'return false;};'
)

def select_text(self, class_name):
"""Programmatically select text on page."""
self.browser.execute_script(
f'var target = document.getElementsByClassName("{class_name}")[0];'
'var range = document.createRange();'
'var selection = window.getSelection();'
'range.selectNode(target);'
'selection.removeAllRanges();'
'selection.addRange(range);'
)

def buy_product(self):
self.browser.get(self.product_path)
self.wait_page_loading()
self.click((By.ID, 'btn-to-basket'))
self.wait.until_not(EC.text_to_be_present_in_element(
(By.CLASS_NAME, 'js-mobile-cart-price'), '0'
))

def go_to_cart(self):
self.click(self.CART_LOCATOR)
self.wait.until(EC.url_contains(self.order_page_url))

def test_download_header_price(self):
"""User clicks Download price button in site's header."""
self.browser.find_element_by_class_name('js-download-price').click()
self.assertTrue('PRICE_HEADER' in self.reached_goals)

def test_download_footer_price(self):
"""User clicks Download price button in site's footer."""
self.browser.find_element_by_class_name('js-download-price-footer').click()
self.assertTrue('PRICE_FOOTER' in self.reached_goals)

def test_backcall_open(self):
"""User clicks Backcall button."""
self.browser.find_element_by_class_name('js-backcall-order').click()
self.assertTrue('BACK_CALL_OPEN' in self.reached_goals)

def test_browse_product_goal_on_index_page(self):
"""User browses to product's page from Index page."""
self.prevent_default('click', '.js-browse-product')
self.click((By.CLASS_NAME, 'js-browse-product'))

self.assertTrue('PROD_BROWSE' in self.reached_goals)

def test_add_product_from_product_page(self):
"""User adds Product to Cart on Product's page."""
self.buy_product()

self.assertTrue('PUT_IN_CART_FROM_PRODUCT' in self.reached_goals)
self.assertTrue('CMN_PUT_IN_CART' in self.reached_goals)

def test_add_product_from_category_page(self):
""""User adds Product to Cart on Category's page."""
self.browser.get(self.category_path)
self.browser.find_element_by_class_name('js-product-to-cart').click()

self.assertTrue('PUT_IN_CART_FROM_CATEGORY' in self.reached_goals)
self.assertTrue('CMN_PUT_IN_CART' in self.reached_goals)

def test_delete_from_dropdown(self):
"""User removes Product from Cart dropdown."""
self.browser.get(self.product_path)
self.buy_product()
removed_el = self.click((By.CLASS_NAME, 'js-cart-remove'))
with self.screen_fail('test_delete_from_dropdown'):
self.wait.until(EC.staleness_of(removed_el))

self.assertTrue('DELETE_PRODUCT' in self.reached_goals)

def test_delete_from_cart_page(self):
"""User removes Product from Cart."""
self.browser.get(self.product_path)
self.buy_product()
self.go_to_cart()
self.browser.find_element_by_class_name('js-remove').click()

self.assertTrue('DELETE_PRODUCT' in self.reached_goals)

def test_use_search(self):
"""User uses search field."""
self.prevent_default('submit', '.js-search-form')
self.browser.find_element_by_class_name('js-search-form').submit()

self.assertTrue('USE_SEARCH_FORM' in self.reached_goals)

def test_backcall_request(self):
"""Test goal when user requested backcall successfully."""
helpers.make_backcall(self.browser)

self.assertTrue('BACK_CALL_SEND' in self.reached_goals)

def test_full_buy_goal(self):
"""User successfully made full Order."""
submit_button_id = 'submit-order'
self.buy_product()
self.go_to_cart()
self.prevent_default('submit', '#order-form-full')
self.browser.find_element_by_id('id_phone').send_keys('22222222222')
self.browser.find_element_by_id('id_email').send_keys('[email protected]')
self.browser.find_element_by_id(submit_button_id).click()
self.wait.until_not(EC.element_to_be_clickable(
(By.ID, submit_button_id)
))

self.assertTrue('FULL_BUY_SEND' in self.reached_goals)
self.assertTrue('CMN_BUY_SEND' in self.reached_goals)

# @todo #718:30m Resurrect `test_cart_page_open` test.
@unittest.skip
def test_cart_page_open(self):
self.buy_product()
self.prevent_default('click', '.js-go-to-cart')
self.click(self.CART_LOCATOR)
self.wait_page_loaded()
self.assertTrue('CART_OPEN' in self.reached_goals)

# @todo #762:30m Match an order with a transaction of Google eCommerce analytics.
# The transaction must contain correct order data and related products.
self.prevent_default('click', '.btn-to-order')
helpers.show_cart_dropdown(self.browser)
self.click((By.CLASS_NAME, 'btn-to-order'))
self.wait_page_loaded()
self.assertTrue('CART_OPEN' in self.reached_goals)
Loading

4 comments on commit 62f3cc9

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 62f3cc9 Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 494-651ceea1 disappeared from shopelectro/tests/tests_selenium.py, that's why I closed #696. Please, remember that the puzzle was not necessarily removed in this particular commit. Maybe it happened earlier, but we discovered this fact only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 62f3cc9 Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 762-c8b88dbe disappeared from shopelectro/tests/tests_js_analytics.py, that's why I closed #771. Please, remember that the puzzle was not necessarily removed in this particular commit. Maybe it happened earlier, but we discovered this fact only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 62f3cc9 Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 762-afab9051 disappeared from shopelectro/tests/tests_selenium.py, that's why I closed #772. Please, remember that the puzzle was not necessarily removed in this particular commit. Maybe it happened earlier, but we discovered this fact only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on 62f3cc9 Mar 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 771-dff73c4b discovered in shopelectro/tests/tests_js_analytics.py and submitted as #785. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but we discovered it only now.

Please sign in to comment.