From 8cbc7c9a0ce543db48f80a743c4168ca847ca500 Mon Sep 17 00:00:00 2001 From: lisinan <1299311192@qq.com> Date: Fri, 24 May 2024 22:00:08 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BF=AB=E9=80=9F?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E4=B8=8B=E4=B8=80=E9=A1=B5=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E9=A2=91=E7=8E=87=E8=BF=87=E5=BF=AB=E6=97=B6?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=B7=B3=E8=BD=AC=E5=88=B0=E6=9C=AA=E7=9F=A5?= =?UTF-8?q?=E5=90=8D=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/userpage_get.html | 211 ++++++++++++++++++++++++-------- app/test/test_next_article.py | 85 +++++++++++++ requirements.txt | 5 +- 3 files changed, 252 insertions(+), 49 deletions(-) create mode 100644 app/test/test_next_article.py diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 68997ef..0488aea 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -5,6 +5,8 @@ + + {{ yml['header'] | safe }} {% if yml['css']['item'] %} @@ -26,12 +28,40 @@ } @keyframes shakes { - 10%, 90% { transform: translate3d(-1px, 0, 0); } - 20%, 50% { transform: translate3d(+2px, 0, 0); } - 30%, 70% { transform: translate3d(-4px, 0, 0); } - 40%, 60% { transform: translate3d(+4px, 0, 0); } - 50% { transform: translate3d(-4px, 0, 0); } + 10%, 90% { + transform: translate3d(-1px, 0, 0); + } + 20%, 50% { + transform: translate3d(+2px, 0, 0); + } + 30%, 70% { + transform: translate3d(-4px, 0, 0); + } + 40%, 60% { + transform: translate3d(+4px, 0, 0); + } + 50% { + transform: translate3d(-4px, 0, 0); + } } + + .lead { + font-size: 22px; + font-family: Helvetica, sans-serif; + white-space: pre-wrap; + } + + .arrow { + padding: 0; + font-size: 20px; + line-height: 21px; + display: inline-block; + } + + .arrow:hover { + cursor: pointer; + } + @@ -39,53 +69,70 @@

English Pal for {{ username }} {% if username == admin_name %} - 管理 + 管理 {% endif %} 退出 重设密码

-{# {% for message in flashed_messages %}#} {# 根据user_service.userpage,取消了参数flashed_messages,因此注释了这段代码 #} -{# #} -{# {% endfor %}#} + {% for message in get_flashed_messages() %} + + {% endfor %} - - + +

阅读文章并回答问题

- -

Article added on: {{ today_article["date"] }}


-

-

{{ today_article["article_title"] }}


-

{{ today_article["article_body"] }}


-

{{ today_article['source'] }}


-

{{ today_article['question'] }}


+ +

Article added on: {{ today_article["date"] }}


+

+

{{ today_article["article_title"] }}


+

{{ today_article["article_body"] }}


+
+

{{ today_article['source'] }}


+
+ +

{{ today_article['question'] }}


-
+ +
- 生词高亮 - 大声朗读 - 划词入库 + 生词高亮 + 大声朗读 + 划词入库
@@ -97,8 +144,8 @@

收集生词吧 (可以在正文中划词,也可以复制黏贴)


- - + +
{% if session.get['thisWord'] %}
{{ yml['footer'] | safe }} @@ -52,5 +53,22 @@ {% endfor %} {% endif %} + diff --git a/app/templates/mainpage_post.html b/app/templates/mainpage_post.html index 7357457..5df7dd5 100644 --- a/app/templates/mainpage_post.html +++ b/app/templates/mainpage_post.html @@ -2,7 +2,7 @@ - Title + 单词词频 {{ yml['header'] | safe }} {% if yml['css']['item'] %} diff --git a/app/templates/reset.html b/app/templates/reset.html index 3425c97..408e001 100644 --- a/app/templates/reset.html +++ b/app/templates/reset.html @@ -12,6 +12,10 @@ alert('输入不能为空!'); return false; } + if (old_password.includes(' ') || new_password.includes(' ')) { + alert('输入不能包含空格!'); + return false; + } if (new_password !== re_new_password) { alert('新密码不匹配,请重新输入'); return false; diff --git a/app/templates/signup.html b/app/templates/signup.html index 9030d41..6b5db6e 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -16,6 +16,10 @@ You're logged in already! Logout. alert('输入不能为空!'); return false; } + if (password.includes(' ') || password2.includes(' ')) { + alert('输入不能包含空格!'); + return false; + } if (password !== password2) { alert('确认密码与输入密码不一致!'); return false; @@ -53,7 +57,7 @@ You're logged in already! Logout.

diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 0488aea..a71c860 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -23,44 +23,34 @@ EnglishPal Study Room for {{ username }} @@ -69,83 +59,72 @@

English Pal for {{ username }} {% if username == admin_name %} - 管理 + 管理 {% endif %} 退出 重设密码

{% for message in get_flashed_messages() %} - + {% endfor %} - - + +

阅读文章并回答问题

- -

Article added on: {{ today_article["date"] }}


+ +

Article added on: {{ today_article["date"] }}



-

{{ today_article["article_title"] }}


-

{{ today_article["article_body"] }}


-
-

{{ today_article['source'] }}


-
+

{{ today_article["article_title"] }}


+

{{ today_article["article_body"] }}


+
+

{{ today_article['source'] }}


+
-

{{ today_article['question'] }}


+

{{ today_article['question'] }}


- -
+
- 生词高亮 - 大声朗读 - 划词入库 + 生词高亮 + 大声朗读 + 划词入库
- +

收集生词吧 (可以在正文中划词,也可以复制黏贴)


- +
{% if session.get['thisWord'] %} - {% endfor %} - {% endif %} + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} - EnglishPal Study Room for {{username}} - - -

取消勾选认识的单词

-
- - {% for x in lst %} - {% set word = x[0]%} -

- {{loop.index}} - : - {{word}} - ({{x[1]}}) - -

+ EnglishPal Study Room for {{username}} + + +
+

+ + +

+ + + {% for x in lst %} + {% set word = x[0]%} +

+ {{loop.index}} + : + {{word}} + ({{x[1]}}) + +

- {% endfor %} - - {{ yml['footer'] | safe }} - {% if yml['js']['bottom'] %} - {% for js in yml['js']['bottom'] %} - - {% endfor %} - {% endif %} - + {% endfor %} + + {{ yml['footer'] | safe }} + {% if yml['js']['bottom'] %} + {% for js in yml['js']['bottom'] %} + + {% endfor %} + {% endif %} +
+ diff --git a/app/test/conftest.py b/app/test/conftest.py index 29f6431..ed4186c 100644 --- a/app/test/conftest.py +++ b/app/test/conftest.py @@ -1,6 +1,9 @@ import pytest +import sqlite3 +import time from selenium import webdriver -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities + +from pathlib import Path @pytest.fixture def URL(): @@ -9,5 +12,24 @@ def URL(): @pytest.fixture def driver(): - my_driver = webdriver.Edge() # uncomment this line if you wish to run the test on your laptop - return my_driver + return webdriver.Edge() # follow the "End-to-end testing" section in README.md to install the web driver executable + + +@pytest.fixture +def restore_sqlite_database(): + ''' + Automatically restore SQLite database file app/db/wordfreqapp.db + using SQL statements from app/static/wordfreqapp.sql + ''' + con = sqlite3.connect('../db/wordfreqapp.db') + with con: + con.executescript('DROP TABLE IF EXISTS user;') + con.executescript('DROP TABLE IF EXISTS article;') + con.executescript(open('../static/wordfreqapp.sql', encoding='utf8').read()) + con.close() + + +@pytest.fixture(autouse=True) +def restart_englishpal(restore_sqlite_database): + (Path(__file__).parent / '../main.py').touch() + time.sleep(1) diff --git a/app/test/helper.py b/app/test/helper.py new file mode 100644 index 0000000..2b0deec --- /dev/null +++ b/app/test/helper.py @@ -0,0 +1,33 @@ +import uuid +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import UnexpectedAlertPresentException, NoAlertPresentException + +def signup(URL, driver): + username = 'TestUser' + str(uuid.uuid1()).split('-')[0].title() + password = '[Abc+123]' + + driver.get(URL) + + elem = driver.find_element_by_link_text('注册') + elem.click() + + elem = driver.find_element_by_id('username') + elem.send_keys(username) + + elem = driver.find_element_by_id('password') + elem.send_keys(password) + + elem = driver.find_element_by_id('password2') + elem.send_keys(password) + + elem = driver.find_element_by_class_name('btn') # 找到"注册"按钮 + elem.click() + + try: + WebDriverWait(driver, 1).until(EC.alert_is_present()) + driver.switch_to.alert.accept() + except (UnexpectedAlertPresentException, NoAlertPresentException): + pass + + return username, password diff --git a/app/test/test_add_word.py b/app/test/test_add_word.py index a08c376..6526bf0 100644 --- a/app/test/test_add_word.py +++ b/app/test/test_add_word.py @@ -1,76 +1,31 @@ -# -*- coding: utf-8 -*- -# Run the docker image using the following command: -# docker run -d -p 4444:4444 selenium/standalone-chrome -from selenium import webdriver -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities - -import random, time -import string - -driver = webdriver.Remote('http://localhost:4444/wd/hub', DesiredCapabilities.FIREFOX) -driver.implicitly_wait(10) - -HOME_PAGE = 'http://121.4.94.30:91/' +import time +from helper import signup -def has_punctuation(s): - return [c for c in s if c in string.punctuation] != [] - -def test_add_word(): +def test_add_word(URL, driver): try: - driver.get(HOME_PAGE) - assert 'English Pal -' in driver.page_source - - # login - elem = driver.find_element_by_link_text('登录') - elem.click() - - uname = 'lanhui' - password = 'l0ve1t' - elem = driver.find_element_by_name('username') - elem.send_keys(uname) - - elem = driver.find_element_by_name('password') - elem.send_keys(password) - - elem = driver.find_element_by_xpath('//form[1]/p[3]/input[1]') # 找到登录按钮 - elem.click() - - assert 'EnglishPal Study Room for ' + uname in driver.title - - # get essay content - elem = driver.find_element_by_id('text-content') - essay_content = elem.text - - elem = driver.find_element_by_id('selected-words') - word = random.choice(essay_content.split()) - while 'font>' in word or 'br>' in word or 'p>' in word or len(word) < 6 or has_punctuation(word): - word = random.choice(essay_content.split()) + username, password = signup(URL, driver) # sign up a new account and automatically log in + time.sleep(1) + # enter the word in the text area + elem = driver.find_element_by_id('selected-words') + word = 'devour' elem.send_keys(word) - elem = driver.find_element_by_xpath('//form[1]//input[1]') # 找到get所有词频按钮 - elem.click() - - elems = driver.find_elements_by_xpath("//input[@type='checkbox']") - for elem in elems: - if elem.get_attribute('name') == 'marked': - elem.click() - - elem = driver.find_element_by_name('add-btn') # 找到加入我的生词簿按钮 + elem = driver.find_element_by_xpath('//form[1]//button[1]') # 找到"把生词加入我的生词库"按钮 + elem.click() + + elem = driver.find_element_by_name('add-btn') # 找到"加入我的生词簿"按钮 elem.click() - driver.refresh() - driver.refresh() - driver.refresh() elems = driver.find_elements_by_xpath("//p[@class='new-word']/a") - + found = 0 for elem in elems: if word in elem.text: found = 1 break - + assert found == 1 - finally: + finally: driver.quit() diff --git a/app/test/test_bug528_tangjiao.py b/app/test/test_bug528_tangjiao.py new file mode 100644 index 0000000..802423c --- /dev/null +++ b/app/test/test_bug528_tangjiao.py @@ -0,0 +1,95 @@ +import pytest +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.common.exceptions import NoSuchElementException, TimeoutException + + +# 测试登录页面输入密码包含空格的情况 +def test_login_password_with_space(driver, URL): + try: + driver.get(URL+"/login") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("test_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 提交登录表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) + + +# 测试注册页面输入密码包含空格的情况 + +def test_signup_password_with_space(driver, URL): + try: + driver.get(URL+"/signup") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("new_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 再次输入密码 + password2_elem = driver.find_element_by_id('password2') + password2_elem.send_keys("password with space") + + # 提交注册表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) + + + +# 测试重设密码页面输入新密码包含空格的情况 + +def test_reset_password_with_space(driver, URL): + try: + driver.get(URL+"/reset") + + # 输入用户名 + username_elem = driver.find_element_by_id('username') + username_elem.send_keys("test_user") + + # 输入包含空格的密码 + password_elem = driver.find_element_by_id('password') + password_elem.send_keys("password with space") + + # 提交重设密码表单 + elem = driver.find_element_by_class_name('btn') # 找到提交按钮 + elem.click() + + # 显式等待直到警告框出现 + WebDriverWait(driver, 10).until(EC.alert_is_present()) + + # 检查是否弹出警告框 + alert = driver.switch_to.alert + assert "输入不能包含空格!" in alert.text + except (NoSuchElementException, TimeoutException) as e: + pytest.fail("页面元素未找到或超时: {}".format(e)) diff --git a/app/test/test_bug544_tangxinyuan.py b/app/test/test_bug544_tangxinyuan.py new file mode 100644 index 0000000..2cffdd4 --- /dev/null +++ b/app/test/test_bug544_tangxinyuan.py @@ -0,0 +1,55 @@ +import random +import string +import time + +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + +from helper import signup + + +def has_punctuation(s): + return any(c in string.punctuation for c in s) + + +def login(driver, home, uname, password): + driver.get(home) + WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, '登录'))).click() + driver.find_element(By.ID, 'username').send_keys(uname) + driver.find_element(By.ID, 'password').send_keys(password) + driver.find_element(By.XPATH, '//button[text()="登录"]').click() + WebDriverWait(driver, 10).until(EC.title_is(f"EnglishPal Study Room for {uname}")) + + +def select_valid_word(driver): + elem = driver.find_element(By.ID, 'text-content') + essay_content = elem.text + valid_word = random.choice([word for word in essay_content.split() if len(word) >= 6 and not has_punctuation( + word) and 'font>' not in word and 'br>' not in word and 'p>' not in word]) + driver.find_element(By.ID, 'selected-words').send_keys(valid_word) + return valid_word + + +def test_save_selected_word(driver, URL): + try: + username, password = signup(URL, driver) + word = select_valid_word(driver) + stored_words = driver.execute_script('return localStorage.getItem("selectedWords");') + assert word == stored_words, "Selected word not saved to localStorage correctly" + # 退出并重新登录以检查存储的单词 + driver.find_element(By.LINK_TEXT, '退出').click() + driver.execute_script("window.open('');window.close();") + + # 等待一会儿,让浏览器有足够的时间关闭标签页 + WebDriverWait(driver, 2) + + # 重新打开一个新的标签页 + driver.execute_script("window.open('');") + driver.switch_to.window(driver.window_handles[-1]) # 切换到新打开的标签页 + + login(driver, URL, username, password) + textarea_content = driver.find_element(By.ID, 'selected-words').get_attribute('value') + assert word == textarea_content, "Selected word not preserved after re-login" + finally: + driver.quit() diff --git a/app/test/test_bug545_HuangHuiLing.py b/app/test/test_bug545_HuangHuiLing.py new file mode 100644 index 0000000..21ddeea --- /dev/null +++ b/app/test/test_bug545_HuangHuiLing.py @@ -0,0 +1,44 @@ +import random +import string +import time +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.action_chains import ActionChains + +from helper import signup + +def has_punctuation(s): + return any(c in string.punctuation for c in s) + +def select_one(driver): + elem = driver.find_element(By.ID, 'article') + essay_content = elem.text + valid_word = random.choice([word for word in essay_content.split() if len(word) >= 6 and not has_punctuation( + word) and 'font>' not in word and 'br>' not in word and 'p>' not in word]) + driver.find_element(By.ID, 'selected-words').send_keys(valid_word) + driver.find_element(By.ID, 'article').click() + return valid_word + +def select_two(driver): + word = driver.find_element(By.CLASS_NAME, 'highlighted') + + # 创建ActionChains对象 + actions = ActionChains(driver) + actions.move_to_element(word) + + # 模拟鼠标按下并拖动以选择文本 + actions.double_click() + actions.perform() + + +def test_selected_second_word(driver, URL): + try: + signup(URL, driver) + selected_words = select_one(driver); + assert selected_words.strip() != "", "选中的单词被放置框中" + select_two(driver) + selected_second_words = driver.find_element(By.ID, 'selected-words').get_attribute('value') + assert selected_second_words.strip() == "", "选中的单词被删除" + finally: + driver.quit() diff --git a/app/test/test_bug546_lixiaofeng.py b/app/test/test_bug546_lixiaofeng.py new file mode 100644 index 0000000..671094b --- /dev/null +++ b/app/test/test_bug546_lixiaofeng.py @@ -0,0 +1,39 @@ +from selenium.webdriver.common.action_chains import ActionChains +from helper import signup + + +def test_highlight(driver, URL): + try: + # 打开网页 + driver.get(URL) + driver.maximize_window() + + # 注册 + signup(URL, driver) + + # 取消勾选“划词入库按钮” + highlight_checkbox = driver.find_element_by_id("chooseCheckbox") + driver.execute_script("arguments[0].click();", highlight_checkbox) + + article = driver.find_element_by_id("article") + + # 创建 ActionChains 对象 + actions = ActionChains(driver) + + # 移动鼠标到起点位置 + actions.move_to_element(article) + # actions.move_to_element_with_offset(article, 50, 100) + # 按下鼠标左键 + actions.click_and_hold() + # 拖动鼠标到结束位置 + actions.move_by_offset(400,50) + # 释放鼠标左键 + actions.release() + # 执行操作链 + actions.perform() + # time.sleep(10) + + assert driver.find_elements_by_class_name("highlighted") is not None + finally: + # 测试结束后关闭浏览器 + driver.quit() \ No newline at end of file diff --git a/app/test/test_bug551_DingZeYu.py b/app/test/test_bug551_DingZeYu.py new file mode 100644 index 0000000..015fb5a --- /dev/null +++ b/app/test/test_bug551_DingZeYu.py @@ -0,0 +1,37 @@ +import time +import pytest +from selenium import webdriver +from selenium.webdriver import ActionChains +from selenium.webdriver.common.by import By +from selenium.webdriver.common.alert import Alert +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.wait import WebDriverWait +from helper import signup + +def test_bug551(driver, URL): + driver.maximize_window() + driver.get(URL) + + username, password = signup(URL, driver) + + article = driver.find_element(By.ID, 'article') + actions = ActionChains(driver) + + actions.move_to_element(article) + actions.click_and_hold() + actions.move_by_offset(450, 200) + actions.release() + actions.perform() + + # 获取选中高亮部分的单词的元素 + highlighted_words = driver.find_elements(By.CLASS_NAME, 'highlighted') + + # 验证选中部分的单词是否同时应用了需求样式 + expected_font_weight = "400" + + for word in highlighted_words: + font_weight = word.value_of_css_property("font-weight") + assert font_weight == expected_font_weight, f"选中部分的单词的字体样式错误" + + time.sleep(5) + driver.quit() diff --git a/app/test/test_bug553_LinShan.py b/app/test/test_bug553_LinShan.py new file mode 100644 index 0000000..388f5da --- /dev/null +++ b/app/test/test_bug553_LinShan.py @@ -0,0 +1,58 @@ +from selenium import webdriver +from selenium.webdriver.common.desired_capabilities import DesiredCapabilities +from selenium.webdriver.support import expected_conditions as EC +from selenium import webdriver +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +import logging +import time +import pytest + +@pytest.mark.parametrize("test_input,expected", + [("‘test1’", "test1"), + ("'test2'", "test2"), + ("“test3”", "test3"), + ("it's", "it's"), + ("hello,I'm linshan", ["hello","i'm","linshan"]), + ("Happy New Year!?", ["happy","new","year"]), + ("My favorite book is 《Harry Potter》。", ["potter","harry","my","favorite","book","is"])]) +def test_bug553_LinShan(test_input,expected, driver, URL): + try: + # 打开对应地址的网页 + driver.get(URL) + + # 浏览器最大窗口化 + driver.maximize_window() + + # 判断网页源代码中是否有English Pal -文字 + assert 'English Pal -' in driver.page_source + + # 将测试的数据输入到主页的textarea里 + driver.find_element_by_xpath("//textarea[@name='content']").send_keys(Keys.CONTROL, "a") + driver.find_element_by_xpath("//textarea[@name='content']").send_keys(test_input) + time.sleep(1) + + # 点击按钮获取单词 + driver.find_element_by_xpath("//input[@value='get文章中的词频']").click() + time.sleep(1) + + # 获取筛选后的单词 + words = driver.find_elements_by_xpath("//p/a") + + # 遍历获取到的单词,并判断单词与预期的相同 + for word in words: + # 判断单词是否在预期结果中 + assert word.text in expected + + # 返回上一页网页 + driver.find_element_by_xpath("//input[@value='确定并返回']").click() + time.sleep(0.1) + + except Exception as e: + # 输出异常信息 + logging.error(e) + # 关闭浏览器 + driver.quit() + finally: + driver.quit() diff --git a/app/test/test_bug561_LiangZiyue.py b/app/test/test_bug561_LiangZiyue.py new file mode 100644 index 0000000..368bc0b --- /dev/null +++ b/app/test/test_bug561_LiangZiyue.py @@ -0,0 +1,27 @@ +import random +import string +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + + +def test_bug561_LiangZiyue(driver, URL): + try: + driver.get(home) + WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, '登录'))).click() + driver.find_element(By.ID, 'username').send_keys("wrr") + driver.find_element(By.ID, 'password').send_keys("1234") + driver.find_element(By.XPATH, '//button[text()="登录"]').click() + ele = driver.find_element(By.XPATH,'//font[@id="article"]') + driver.execute_script('arguments[0].scrollIntoView();',ele) + action = ActionChains(driver) + action.click_and_hold(ele) + action.move_by_offset(0,500) + action.perform() + next_ele = driver.find_element(By.ID,'//button[@id="load_next_article"]') + driver.execute_script('arguments[0].scrollIntoView();',next_ele) + next_ele.click() + driver.execute_script('arguments[0].scrollIntoView();',ele) + ele.click() + finally: + driver.quit() \ No newline at end of file diff --git a/app/test/test_stress.py b/app/test/test_stress.py new file mode 100755 index 0000000..b437b86 --- /dev/null +++ b/app/test/test_stress.py @@ -0,0 +1,43 @@ +''' Contributed by Lin Junhong et al. 2023-06.''' + +import requests +import multiprocessing +import time + +def stress(username): + try: + data = { + 'username': username, + 'password': '123123' + } + headers = { + 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36 Edg/114.0.1823.51' + } + session = requests.session() + response = session.post(url='http://127.0.0.1:5000/signup', data=data, headers=headers) + print('Sign up ', response.status_code) + time.sleep(0.5) + response = session.post(url='http://127.0.0.1:5000/login', data=data, headers=headers) + print('Sign in ', response.status_code) + time.sleep(0.5) + response = session.get(url=f'http://127.0.0.1:5000/{username}/userpage', headers=headers) + print('User page', response.status_code) + time.sleep(0.5) + print(session.cookies) + for i in range(5): + response = session.get(url=f'http://127.0.0.1:5000/get_next_article/{username}', headers=headers, cookies=session.cookies) + time.sleep(0.5) + print(f'Next page ({i}) [{username}]') + print(response.status_code) + print(response.json()['today_article']['article_title']) + except Exception as e: + print(e) + + +if __name__ == '__main__': + username = 'Learner' + pool = multiprocessing.Pool(processes=10) + for i in range(10): + pool.apply_async(stress, (f'{username}{i}',)) + pool.close() + pool.join() diff --git a/app/user_service.py b/app/user_service.py index 2e5feed..27323b8 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -15,6 +15,9 @@ from wordfreqCMD import sort_in_descending_order import pickle_idea import pickle_idea2 +import logging +logging.basicConfig(filename='log.txt', format='%(asctime)s %(message)s', level=logging.DEBUG) + # 初始化蓝图 userService = Blueprint("user_bp", __name__) @@ -32,7 +35,9 @@ def get_next_article(username): else: # 当前不为“null”,直接 index+=1 visited_articles["index"] += 1 session["visited_articles"] = visited_articles + logging.debug('/get_next_article: start calling get_today_arcile()') visited_articles, today_article, result_of_generate_article = get_today_article(user_freq_record, session.get('visited_articles')) + logging.debug('/get_next_arcile: done.') data = { 'visited_articles': visited_articles, 'today_article': today_article, @@ -129,7 +134,7 @@ def userpage(username): user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) if request.method == 'POST': # when we submit a form - content = escape(request.form['content']) + content = request.form['content'] f = WordFreq(content) lst = f.get_freq() return render_template('userpage_post.html',username=username,lst = lst, yml=Yaml.yml) @@ -176,7 +181,11 @@ def user_mark_word(username): for word in request.form.getlist('marked'): lst.append((word, [get_time()])) d = pickle_idea2.merge_frequency(lst, lst_history) - pickle_idea2.save_frequency_to_pickle(d, user_freq_record) + if len(lst_history) > 999: + flash('You have way too many words in your difficult-words book. Delete some first.') + else: + pickle_idea2.save_frequency_to_pickle(d, user_freq_record) + flash('Added %s.' % (', '.join(request.form.getlist('marked')))) return redirect(url_for('user_bp.userpage', username=username)) else: return 'Under construction' diff --git a/app/wordfreqCMD.py b/app/wordfreqCMD.py index dcee74e..feeafbd 100644 --- a/app/wordfreqCMD.py +++ b/app/wordfreqCMD.py @@ -4,6 +4,7 @@ ########################################################################### import collections +import html import string import operator import os, sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。 @@ -39,7 +40,8 @@ def file2str(fname):#文件转字符 def remove_punctuation(s): # 这里是s是形参 (parameter)。函数被调用时才给s赋值。 - special_characters = '\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|' # 把里面的字符都去掉 + special_characters = '\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|,。?!¥……()、《》:;·' # 把里面的字符都去掉 + s = html.unescape(s) # 将HTML实体转换为对应的字符,比如<会被识别为小于号 for c in special_characters: s = s.replace(c, ' ') # 防止出现把 apple,apple 移掉逗号后变成 appleapple 情况 s = s.replace('--', ' ') @@ -104,7 +106,7 @@ if __name__ == '__main__': print('%s\t%d\t%s' % (x[0], x[1], youdao_link(x[0])))#函数导出 # 把频率的结果放result.html中 - make_html_page(sort_in_descending_order(L), 'result.html') + make_html_page(sort_in_descending_order(L), 'result.html') print('\nHistory:\n') if os.path.exists('frequency.p'): diff --git a/build.sh b/build.sh index e313fce..158a86f 100755 --- a/build.sh +++ b/build.sh @@ -2,10 +2,7 @@ DEPLOYMENT_DIR=/home/lanhui/englishpal2/EnglishPal cd $DEPLOYMENT_DIR - -# Install dependencies - -pip3 install -r requirements.txt +pwd # Stop service sudo docker stop EnglishPal @@ -15,7 +12,7 @@ sudo docker rm EnglishPal sudo docker build -t englishpal . # Run the application -sudo docker run --restart=always -d --name EnglishPal -p 90:80 -v ${DEPLOYMENT_DIR}/app/static/frequency:/app/static/frequency -v ${DEPLOYMENT_DIR}/app/static/:/app/static/ -t englishpal # for permanently saving data +sudo docker run --restart=always -d --name EnglishPal -p 90:80 -v ${DEPLOYMENT_DIR}/app/static/frequency:/app/static/frequency --mount type=volume,src=englishpal-db,target=/app/db -t englishpal # for permanently saving data # Save space. Run it after sudo docker run sudo docker system prune -a -f