forked from mrlan/EnglishPal
Compare commits
50 Commits
Bug561-Wan
...
Bug546-Lix
Author | SHA1 | Date |
---|---|---|
lixiaofeng | e3db7c30b0 | |
lixiaofeng | 9f03cc49fa | |
lixiaofeng | eed852cd66 | |
lixiaofeng | c6f8a3448d | |
黄慧玲 | d8af2a7e54 | |
1994836463@qq.com | a0c9b82ee7 | |
1994836463@qq.com | 4a42c5c22c | |
1994836463@qq.com | 101c359596 | |
1994836463@qq.com | 64a82bee22 | |
1994836463@qq.com | 9537024339 | |
1994836463@qq.com | 85a3a9ce6a | |
1994836463@qq.com | f3b9fd8790 | |
1994836463@qq.com | 624426b6cf | |
1994836463@qq.com | d1589f6062 | |
1994836463@qq.com | fcd2c83904 | |
1994836463@qq.com | 29a673cd92 | |
1994836463@qq.com | 1bec0bd107 | |
1994836463@qq.com | 630cb6befa | |
黄慧玲 | 5dbdf60a2c | |
1994836463@qq.com | 101506a511 | |
丁晟晔 | d8e4fbbb2d | |
1994836463@qq.com | 9b3551bbc8 | |
1994836463@qq.com | 90ac789bb4 | |
1994836463@qq.com | 8575a0dc33 | |
黄慧玲 | 3373ba1429 | |
黄慧玲 | d296580b3b | |
Lan Hui | a4db1edffb | |
丁晟晔 | 49ead93bcb | |
丁晟晔 | 9afd38a09a | |
丁晟晔 | d97743649a | |
丁晟晔 | 9f6a007426 | |
丁晟晔 | 7fe3feae9a | |
丁晟晔 | b2a53a0e40 | |
丁晟晔 | 0301c39cf0 | |
丁晟晔 | 5857395251 | |
丁晟晔 | 77ed63441b | |
丁晟晔 | b19eabd225 | |
丁晟晔 | b9d0ad4a15 | |
丁晟晔 | aca827a912 | |
丁晟晔 | 23f0dfd8ca | |
丁晟晔 | 6ee94d1610 | |
丁晟晔 | 416f40222e | |
丁晟晔 | 66f5c28ead | |
丁晟晔 | ff6286cf01 | |
丁晟晔 | 1d7e61d751 | |
丁晟晔 | c9c0ef60d8 | |
丁晟晔 | 393264a6fe | |
丁晟晔 | d5c76674da | |
丁晟晔 | b8222c951b | |
dingchengye | 4120e7e54b |
|
@ -2,7 +2,7 @@
|
|||
css:
|
||||
item:
|
||||
- ../static/css/bootstrap.css
|
||||
|
||||
- ../static/css/highlighted.css
|
||||
# 全局引入的js文件地址
|
||||
js:
|
||||
head: # 在页面加载之前加载
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
.highlighted {
|
||||
color: red;
|
||||
font-weight: normal;
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
// initialize from localStorage
|
||||
let isRead = localStorage.getItem('readChecked') !== 'false'; // default to true
|
||||
let isChoose = localStorage.getItem('chooseChecked') !== 'false';
|
||||
|
||||
|
@ -9,8 +8,15 @@ function getWord() {
|
|||
function fillInWord() {
|
||||
let word = getWord();
|
||||
if (isRead) Reader.read(word, inputSlider.value);
|
||||
if (!isChoose) return;
|
||||
if (!isChoose) {
|
||||
if(isHighlight){
|
||||
const element = document.getElementById("selected-words3");
|
||||
element.value = element.value + " " + word;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const element = document.getElementById("selected-words");
|
||||
localStorage.setItem('nowWords', element.value);
|
||||
element.value = element.value + " " + word;
|
||||
localStorage.setItem('selectedWords', element.value);
|
||||
}
|
||||
|
@ -38,3 +44,4 @@ function onChooseClick() {
|
|||
if (performance.getEntriesByType("navigation")[0].type == "reload") {
|
||||
Reader.stopRead();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,38 +22,48 @@ function getWord() {
|
|||
|
||||
function highLight() {
|
||||
if (!isHighlight) return;
|
||||
let word = (getWord() + "").trim();
|
||||
let articleContent = document.getElementById("article").innerHTML; // innerHTML保留HTML标签来保持部分格式,且适配不同的浏览器
|
||||
let pickedWords = document.getElementById("selected-words"); // words picked to the text area
|
||||
let dictionaryWords = document.getElementById("selected-words2"); // words appearing in the user's new words list
|
||||
let allWords = dictionaryWords === null ? pickedWords.value + " " : pickedWords.value + " " + dictionaryWords.value;
|
||||
highlightWords = document.getElementById("selected-words3");
|
||||
allWords = highlightWords == null ? allWords : allWords + " " + highlightWords.value;
|
||||
const list = allWords.split(" "); // 将所有的生词放入一个list中
|
||||
if(word !== null && word !== "" && word !== " "){
|
||||
let articleContent_fb2 = articleContent;
|
||||
if(localStorage.getItem("nowWords").indexOf(word) !== -1 || localStorage.getItem("nowWords").indexOf(word.toLowerCase()) !== -1){
|
||||
articleContent = articleContent.replace(new RegExp('<span class="highlighted">' + word + '</span>', "gi"), word);
|
||||
pickedWords.value = localStorage.getItem("nowWords").replace(word,"");
|
||||
document.getElementById("article").innerHTML = articleContent;
|
||||
return;
|
||||
}
|
||||
}
|
||||
let totalSet = new Set();
|
||||
for (let i = 0; i < list.length; ++i) {
|
||||
list[i] = list[i].replace(/(^\W*)|(\W*$)/g, ""); // 消除单词两边的非单词字符
|
||||
list[i] = list[i].replace('|', "");
|
||||
list[i] = list[i].replace('?', "");
|
||||
if (list[i] != "" && !totalSet.has(list[i])) {
|
||||
// 返回所有匹配单词的集合, 正则表达式RegExp()中, "\b"匹配一个单词的边界, g 表示全局匹配, i 表示对大小写不敏感。
|
||||
let matches = new Set(articleContent.match(new RegExp("\\b" + list[i] + "\\b", "gi")));
|
||||
if (matches.has("mark")) {
|
||||
// 优先处理单词为 "mark" 的情况
|
||||
totalSet = new Set(["mark", ...totalSet]);
|
||||
}
|
||||
totalSet = new Set([...totalSet, ...matches]);
|
||||
}
|
||||
}
|
||||
// 删除所有的mark标签,防止标签发生嵌套
|
||||
articleContent = articleContent.replace(/<(mark)[^>]*>/gi, "");
|
||||
articleContent = articleContent.replace(/<(\/mark)[^>]*>/gi, "");
|
||||
// 将文章中所有出现该单词word的地方改为:"<mark>" + word + "<mark>"。
|
||||
// 删除所有的"<span class='highlighted'>"标签,防止标签发生嵌套
|
||||
articleContent = articleContent.replace(new RegExp('<span class="highlighted">',"gi"), "")
|
||||
articleContent = articleContent.replace(new RegExp("</span>","gi"), "");
|
||||
// 将文章中所有出现该单词word的地方改为:"<span class='highlighted'>" + word + "</span>"。
|
||||
for (let word of totalSet) {
|
||||
articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "<mark>" + word + "</mark>");
|
||||
articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "<span class='highlighted'>" + word + "</span>");
|
||||
}
|
||||
document.getElementById("article").innerHTML = articleContent;
|
||||
}
|
||||
|
||||
function cancelHighlighting() {
|
||||
let articleContent = document.getElementById("article").innerHTML;
|
||||
articleContent = articleContent.replace(/<(mark)[^>]*>/gi, "");
|
||||
articleContent = articleContent.replace(/<(\/mark)[^>]*>/gi, "");
|
||||
articleContent = articleContent.replace(new RegExp('<span class="highlighted">',"gi"), "")
|
||||
articleContent = articleContent.replace(new RegExp("</span>","gi"), "");
|
||||
document.getElementById("article").innerHTML = articleContent;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
<input id="selected-words2" type="hidden" value="{{ words }}">
|
||||
{% endif %}
|
||||
</div>
|
||||
<label id="selected-words3" type="hidden"></label>
|
||||
{{ yml['footer'] | safe }}
|
||||
{% if yml['js']['bottom'] %}
|
||||
{% for js in yml['js']['bottom'] %}
|
||||
|
@ -232,9 +233,6 @@
|
|||
update(data['today_article']);
|
||||
check_pre(data['visited_articles']);
|
||||
check_next(data['result_of_generate_article']);
|
||||
// 在加载新文章后调用高亮函数
|
||||
toggleHighlighting();
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -248,8 +246,6 @@
|
|||
if(data['today_article']){
|
||||
update(data['today_article']);
|
||||
check_pre(data['visited_articles']);
|
||||
// 在加载新文章后调用高亮函数
|
||||
toggleHighlighting();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -296,7 +292,7 @@
|
|||
</body>
|
||||
<style>
|
||||
mark {
|
||||
color: #{{ yml['highlight']['color'] }};
|
||||
color: red;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
|
@ -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()
|
|
@ -1,69 +0,0 @@
|
|||
import time
|
||||
import pytest
|
||||
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.common.exceptions import NoSuchElementException, TimeoutException
|
||||
from selenium.webdriver import ActionChains
|
||||
|
||||
# 导入 app/test/conftest.py 中的 signup 函数
|
||||
from app.test.conftest import signup
|
||||
|
||||
def select_text_in_article(driver):
|
||||
elem = driver.find_element(By.CSS_SELECTOR, '#article')
|
||||
|
||||
action = ActionChains(driver)
|
||||
# 从左上角点击并按住
|
||||
action.move_to_element_with_offset(elem, 0, 0)
|
||||
action.click_and_hold()
|
||||
# 移动到右下角的某个位置(例如,右下角偏移100, 100)
|
||||
action.move_by_offset(100, 100)
|
||||
action.release()
|
||||
action.perform()
|
||||
|
||||
def verify_highlight(driver):
|
||||
# 检查是否有高亮的元素
|
||||
highlighted_elements = driver.execute_script("""
|
||||
return Array.from(document.querySelectorAll('#article mark')).map(mark => mark.innerText);
|
||||
""")
|
||||
print("Highlighted elements:", highlighted_elements)
|
||||
return len(highlighted_elements) > 0
|
||||
|
||||
def test_bug561(URL, driver):
|
||||
try:
|
||||
driver.maximize_window()
|
||||
username, password = signup(URL, driver)
|
||||
|
||||
time.sleep(3) # 等待页面加载完成
|
||||
|
||||
select_text_in_article(driver)
|
||||
if verify_highlight(driver):
|
||||
print("Text highlighted after selection")
|
||||
else:
|
||||
print("No text highlighted after selection")
|
||||
|
||||
# 点击“下一页”按钮
|
||||
next_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'load_next_article')))
|
||||
next_button.click()
|
||||
print("Clicked next article button.")
|
||||
|
||||
# 等待“上一页”按钮加载完成
|
||||
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'load_pre_article')))
|
||||
print("Next article loaded.")
|
||||
|
||||
# 点击“上一页”按钮
|
||||
prev_button = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, 'load_pre_article')))
|
||||
prev_button.click()
|
||||
print("Clicked previous article button.")
|
||||
|
||||
# 确认高亮是否保留
|
||||
if verify_highlight(driver):
|
||||
print("Highlighted text preserved after switching articles")
|
||||
else:
|
||||
print("Highlighted text not preserved after switching articles")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error during test: {e}")
|
||||
finally:
|
||||
driver.quit()
|
||||
print("Driver closed.")
|
Loading…
Reference in New Issue