Покрыть тестами - заполнение курсов.

remotes/origin/feature/testing_courses_30-01-19
gzbender 7 years ago
parent 327925c7ba
commit 2eef7078eb
  1. 35
      apps/content/tests/mixins.py
  2. 17
      apps/course/tests/test_views.py
  3. 14
      project/tests/__init__.py
  4. 51
      project/utils/selenium_utils.py
  5. 7
      web/src/components/CourseRedactor.vue

@ -3,6 +3,7 @@ import time
from factory.faker import Faker
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from django.utils.html import strip_tags
class TestContentMixin:
@ -22,8 +23,9 @@ class TestContentMixin:
for i, item in enumerate(object.content.all().order_by('position', '-created_at',)):
item_data = self.content_data[i].get('data')
for key, value in item_data.items():
print('real obj field value:', getattr(item, key, None))
print('expected value:', value)
if key == 'txt':
self.assertEqual(strip_tags(getattr(item, key)), value)
else:
self.assertEqual(getattr(item, key), value)
print('OK')
@ -34,7 +36,7 @@ class TestContentMixin:
open_el = self.wait_elem_name('block-add-open', block_add_el)
self.assertRaises(TimeoutException, lambda: self.wait_elem_name('block-add-close', block_add_el))
open_el.click()
time.sleep(1)
time.sleep(0.5)
close_el = self.wait_elem_name('block-add-close', block_add_el)
block_text_el = self.wait_elem_name('block-add-block-text', block_add_el)
@ -42,21 +44,29 @@ class TestContentMixin:
time.sleep(0.5)
self.check_block_text(inside_el)
open_el.click()
time.sleep(0.5)
block_image_el = self.wait_elem_name('block-add-block-image', block_add_el)
block_image_el.click()
time.sleep(0.5)
self.check_block_image(inside_el)
open_el.click()
time.sleep(0.5)
block_image_text_el = self.wait_elem_name('block-add-block-image-text', block_add_el)
block_image_text_el.click()
time.sleep(0.5)
self.check_block_image_text(inside_el)
open_el.click()
time.sleep(0.5)
block_images_el = self.wait_elem_name('block-add-block-images', block_add_el)
block_images_el.click()
time.sleep(0.5)
self.check_block_images(inside_el)
open_el.click()
time.sleep(0.5)
block_video_el = self.wait_elem_name('block-add-block-video', block_add_el)
block_video_el.click()
time.sleep(0.5)
@ -68,8 +78,7 @@ class TestContentMixin:
block_obj = {'type': 'text', 'data': {}}
block_el = self.wait_elem_name('block-text', inside_el)
title_el = self.wait_elem_name('block-text-title', block_el)
text_el = self.wait_elem_name('block-text-text-wrap', block_el)
text_el.find_element(
text_el = self.wait_elem_name('block-text-text-wrap', block_el).find_element(
By.XPATH, './/div[contains(@class, "redactor-layer")][@contenteditable]')
self.content_data.append(block_obj)
@ -77,11 +86,9 @@ class TestContentMixin:
title_el.send_keys(title)
block_obj['data']['title'] = title
text = Faker('sentence', nb_words=50).generate({})
self.driver.execute_script("arguments[0].click();", text_el)
self.driver.execute_script("arguments[0].innerHtml = arguments[1];", text_el, text)
self.driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", text_el)
# text_el.send_keys(text)
block_obj['data']['text'] = '<p>%s</p>' % text
text_el.click()
text_el.send_keys(text)
block_obj['data']['txt'] = text
self.check_auto_saving()
def check_block_image(self, inside_el=None):
@ -114,11 +121,9 @@ class TestContentMixin:
title_el.send_keys(title)
block_obj['data']['title'] = title
text = Faker('sentence', nb_words=50).generate({})
self.driver.execute_script("arguments[0].click();", text_el)
self.driver.execute_script("arguments[0].innerHtml = arguments[1];", text_el, text)
self.driver.execute_script("arguments[0].dispatchEvent(new Event('change'));", text_el)
# text_el.send_keys(text)
block_obj['data']['text'] = '<p>%s</p>' % text
text_el.click()
text_el.send_keys(text)
block_obj['data']['txt'] = text
# TODO: check image upload
self.check_auto_saving()

@ -1,8 +1,8 @@
from datetime import timedelta
from random import randint
import time
import re
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from factory.faker import Faker
from django.utils import timezone
@ -70,9 +70,11 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
super().tearDownClass()
def check_auto_saving(self):
# TODO
time.sleep(5)
time.sleep(0.5)
request = self.wait_for_request(f'/api/v1/courses/{self.object_id}/')
obj = self.model.objects.get(id=self.object_id)
self.assertEqual(request[2].get('status'), 200)
self.assertNotEqual(request[2].get('response'), None)
for key, value in self.object_data.items():
if key != 'content':
self.assertEqual(getattr(obj, key), value)
@ -85,6 +87,8 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
print('url is', url)
self.driver.get(url)
print('page opened', self.driver.current_url)
self.add_requests_log()
course_redactor = self.wait_elem_name('course-redactor')
# visible always elements
title_el = self.wait_elem_name('course-title')
@ -106,11 +110,11 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
title = Faker('sentence', nb_words=6).generate({})
title_el.send_keys(title)
slug = slugify(unidecode(title[:90]))
slug = re.sub(r'[^-\w]+$', '', slug)
slug = re.sub(r'[^-\w]', '-', slug)
self.object_data['title'] = title
self.object_data['slug'] = slug
# print('title:', title)
# print('slug:', slug)
time.sleep(2)
time.sleep(1)
self.assertEqual(slug_el.get_attribute('value'), slug)
# check save
@ -151,4 +155,3 @@ class CourseEditTestCase(TestContentMixin, SeleniumTestCase):
# lesson_edit_el = self.wait_elem_name('course-lesson-edit')
# stream_el = self.wait_elem_name('course-stream')

@ -3,6 +3,8 @@ from selenium import webdriver
from selenium.webdriver.common.by import By
from pyvirtualdisplay import Display
from django.conf import settings
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from project.utils.selenium_utils import SeleniumExtensions as SE
from apps.auth.models import TempToken
@ -15,7 +17,7 @@ class SeleniumTestCase(LiveServerTestCase ):
super().setUpClass()
cls.display = Display(visible=0, size=(1280, 1024))
cls.display.start()
cls.driver = webdriver.Chrome()
cls.driver = webdriver.Firefox()
@classmethod
def tearDownClass(cls):
@ -48,6 +50,16 @@ class SeleniumTestCase(LiveServerTestCase ):
return SE.wait_elems(self.driver, (By.NAME, name), inside_el, wait_time)
def login(self, user):
TempToken.objects.all().delete()
tt = TempToken.objects.create(user=user)
self.driver.get('%s?temp-token=%s' % (self.get_url(), tt.key))
def add_requests_log(self):
SE.add_requests_log(self.driver)
def get_requests(self):
return SE.get_requests(self.driver)
def wait_for_request(self, path, wait_time=10):
return SE.wait_for_request(self.driver, path, wait_time)

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
@ -44,3 +42,52 @@ class SeleniumExtensions(object):
return WebDriverWait(driver, wait_time).until(
EC.presence_of_all_elements_located(locator)
)
@classmethod
def wait_for_js_load(cls, driver, wait_time=10):
WebDriverWait(driver, wait_time).until(
lambda driver: driver.execute_script('return document.readyState') == 'complete')
@classmethod
def add_requests_log(cls, driver):
js = '''
(function() {
var open = XMLHttpRequest.prototype.open;
var send = XMLHttpRequest.prototype.send;
window._requestsLog = [];
window._findRequest = function(pathOrXHR){
for(var i=window._requestsLog.length - 1; i >= 0; i--){
var request = window._requestsLog[i];
if(typeof(pathOrXHR) == 'string' && request[1].indexOf(pathOrXHR) > -1
|| request[2] === pathOrXHR){
return request;
}
}
}
XMLHttpRequest.prototype.open = function(method, url){
window._requestsLog.push([method, url, this]);
return open.apply(this, arguments);
}
XMLHttpRequest.prototype.send = function(body){
var r = window._findRequest(this);
if(r){
r.push(body);
}
return send.apply(this, arguments);
}
})();
'''
return driver.execute_script(js)
@classmethod
def get_requests(cls, driver):
return driver.execute_script('return window._requestsLog;')
@classmethod
def wait_for_request(cls, driver, path, wait_time=10):
WebDriverWait(driver, wait_time).until(
lambda driver: driver.execute_script('''
var r = window._findRequest(arguments[0]);
return !!r && r[2].readyState == 4;
''', path) is True)
return driver.execute_script('return window._findRequest(arguments[0]);', path)

@ -487,10 +487,13 @@
onCoursePriceChange(event) {
this.course.price = event.target.value;
},
getSlug(text) {
return slugify(text || '').toLowerCase().replace(/[^-\w]+$/, '').replace(/[^-\w]/g, '-');
},
onCourseNameInput() {
this.$v.course.title.$touch();
if (!this.slugChanged && !this.$v.course.status) {
this.course.slug = (slugify(this.course.title) || '').toLowerCase();
this.course.slug = this.getSlug(this.course.title);
}
},
removeLesson(lessonIndex) {
@ -767,7 +770,7 @@
this.courseSaving = true;
this.changeSavingStatus();
const courseObject = this.course;
courseObject.slug = courseObject.slug && slugify(courseObject.slug);
courseObject.slug = this.getSlug(courseObject.slug);
api.saveCourse(courseObject, this.accessToken)
.then((response) => {
this.courseSaving = false;

Loading…
Cancel
Save