forked from mrlan/EnglishPal
				
			Fix bug 544
							parent
							
								
									7d5b1c0ed4
								
							
						
					
					
						commit
						2966a8162f
					
				|  | @ -1,5 +1,5 @@ | |||
| let isRead = true; | ||||
| let isChoose = true; | ||||
| let isRead = localStorage.getItem('readChecked') !== 'false'; | ||||
| let isChoose = localStorage.getItem('chooseChecked') !== 'false'; | ||||
| 
 | ||||
| function getWord() { | ||||
|     return window.getSelection ? window.getSelection() : document.selection.createRange().text; | ||||
|  | @ -11,6 +11,7 @@ function fillInWord() { | |||
|     if (!isChoose) return; | ||||
|     const element = document.getElementById("selected-words"); | ||||
|     element.value = element.value + " " + word; | ||||
|     localStorage.setItem('selectedWords', element.value); | ||||
| } | ||||
| 
 | ||||
| document.getElementById("text-content").addEventListener("click", fillInWord, false); | ||||
|  | @ -24,10 +25,12 @@ inputSlider.oninput = () => { | |||
| 
 | ||||
| function onReadClick() { | ||||
|     isRead = !isRead; | ||||
|     localStorage.setItem('readChecked', isRead); | ||||
| } | ||||
| 
 | ||||
| function onChooseClick() { | ||||
|     isChoose = !isChoose; | ||||
|     localStorage.setItem('chooseChecked', isChoose); | ||||
| } | ||||
| 
 | ||||
| // 如果网页刷新,停止播放声音
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| let isHighlight = true; | ||||
| let isHighlight = localStorage.getItem('highlightChecked') !== 'false'; | ||||
| 
 | ||||
| function cancelBtnHandler() { | ||||
|     cancelHighlighting(); | ||||
|  | @ -73,6 +73,7 @@ function toggleHighlighting() { | |||
|         isHighlight = true; | ||||
|         highLight(); | ||||
|     } | ||||
|      localStorage.setItem('highlightChecked', isHighlight); | ||||
| } | ||||
| 
 | ||||
| showBtnHandler(); | ||||
										
											Binary file not shown.
										
									
								
							|  | @ -34,9 +34,9 @@ | |||
|         <div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇</div> | ||||
|         <p>粘贴1篇文章 (English only)</p> | ||||
|         <form method="post" action="/"> | ||||
|             <textarea name="content" rows="10" cols="120"></textarea><br/> | ||||
|             <textarea name="content" id="article" rows="10" cols="120"></textarea><br/> | ||||
|             <input type="submit" value="get文章中的词频"/> | ||||
|             <input type="reset" value="清除"/> | ||||
|             <input type="reset" value="清除" onclick="clearArticle()"/> | ||||
|         </form> | ||||
|         {% if d_len > 0 %} | ||||
|             <p><b>最常见的词</b></p> | ||||
|  | @ -53,5 +53,20 @@ | |||
|             <script src="{{ js }}" ></script> | ||||
|         {% endfor %} | ||||
|     {% endif %} | ||||
| <script type="text/javascript"> | ||||
|     window.onload = function() { | ||||
|         document.getElementById('article').value = localStorage.getItem('article') || ''; | ||||
|     } | ||||
|     document.getElementById('article').addEventListener('input', saveArticle); | ||||
| 
 | ||||
|     function saveArticle() { | ||||
|         localStorage.setItem('article', document.getElementById('article').value); | ||||
|     } | ||||
| 
 | ||||
|     function clearArticle() { | ||||
|         localStorage.removeItem('article'); | ||||
|     } | ||||
| 
 | ||||
| </script> | ||||
| </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -109,22 +109,22 @@ | |||
|         </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <input type="checkbox" onclick="toggleHighlighting()" checked/>生词高亮 | ||||
|     <input type="checkbox" onclick="onReadClick()" checked/>大声朗读 | ||||
|     <input type="checkbox" onclick="onChooseClick()" checked/>划词入库 | ||||
|     <input type="checkbox" id="highlightCheckbox" onclick="toggleHighlighting()" />生词高亮 | ||||
|     <input type="checkbox" id="readCheckbox" onclick="onReadClick()" />大声朗读 | ||||
|     <input type="checkbox" id="chooseCheckbox" onclick="onChooseClick()" />划词入库 | ||||
|     <div class="range"> | ||||
|         <div class="field"> | ||||
|             <div class="sliderValue"> | ||||
|                 <span id="rangeValue">1×</span> | ||||
|             </div> | ||||
|             <input type="range" id="rangeComponent" min="0.5" max="2" value="1" step="0.25"/> | ||||
|             <input type="range" id="rangeComponent" min="0.5" max="2" value="1" step="0.25" onchange="saveRangeValue()" /> | ||||
|         </div> | ||||
|     </div> | ||||
|     <p><b>收集生词吧</b> (可以在正文中划词,也可以复制黏贴)</p> | ||||
|     <form method="post" action="/{{ username }}/userpage"> | ||||
|         <textarea name="content" id="selected-words" rows="10" cols="120"></textarea><br/> | ||||
|         <button class="btn btn-primary btn-lg" type="submit" onclick="Reader.stopRead()">把生词加入我的生词库</button> | ||||
|         <button class="btn btn-primary btn-lg" type="reset">清除</button> | ||||
|         <button class="btn btn-primary btn-lg" type="reset"  onclick="clearSelectedWords()">清除</button> | ||||
|     </form> | ||||
|     {% if session.get['thisWord'] %} | ||||
|         <script type="text/javascript"> | ||||
|  | @ -174,11 +174,41 @@ | |||
| {% endif %} | ||||
| <script type="text/javascript"> | ||||
|     window.onload = function () { // 页面加载时执行 | ||||
|         const highlightChecked = localStorage.getItem('highlightChecked') !== 'false'; | ||||
|         const readChecked = localStorage.getItem('readChecked') !== 'false'; | ||||
|         const chooseChecked = localStorage.getItem('chooseChecked') !== 'false'; | ||||
|         const rangeValue = localStorage.getItem('rangeValue') || '1'; | ||||
|         const selectedWords = localStorage.getItem('selectedWords') || ''; | ||||
| 
 | ||||
|         document.getElementById('highlightCheckbox').checked = highlightChecked; | ||||
|         document.getElementById('readCheckbox').checked = readChecked; | ||||
|         document.getElementById('chooseCheckbox').checked = chooseChecked; | ||||
|         document.getElementById('rangeComponent').value = rangeValue; | ||||
|         document.getElementById('rangeValue').innerHTML = rangeValue + 'x'; | ||||
|         document.getElementById('selected-words').value = selectedWords; | ||||
| 
 | ||||
|         // 刷新页面或进入页面时判断,若不是首篇文章,则上一篇按钮可见 | ||||
|         if(sessionStorage.getItem('pre_page_button')!="display" && sessionStorage.getItem('pre_page_button')){ | ||||
|             $('#load_pre_article').show(); | ||||
|         } | ||||
|      }; | ||||
|     document.getElementById('selected-words').addEventListener('input', saveSelectedWords); | ||||
| 
 | ||||
|     function saveSelectedWords() { | ||||
|         let selectedWordsTextarea = document.getElementById('selected-words'); | ||||
|         localStorage.setItem('selectedWords', selectedWordsTextarea.value); | ||||
|     } | ||||
| 
 | ||||
|     function clearSelectedWords() { | ||||
|         localStorage.removeItem('selectedWords'); | ||||
|     } | ||||
| 
 | ||||
|     function saveRangeValue() { | ||||
|         const rangeValue = document.getElementById('rangeComponent').value; | ||||
|         document.getElementById('rangeValue').textContent = rangeValue; | ||||
|         localStorage.setItem('rangeValue', rangeValue); | ||||
|     } | ||||
| 
 | ||||
|     function load_next_article(){ | ||||
|         $.ajax({ | ||||
|             url: '/get_next_article/{{username}}', | ||||
|  |  | |||
|  | @ -1,50 +1,50 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|     <head> | ||||
| 	<meta charset="UTF-8"> | ||||
| 	<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" /> | ||||
| 	<meta name="format-detection" content="telephone=no" /> | ||||
|        <meta charset="UTF-8"> | ||||
|        <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" /> | ||||
|        <meta name="format-detection" content="telephone=no" /> | ||||
| 
 | ||||
| 	{{ yml['header'] | safe }} | ||||
| 	{% if yml['css']['item'] %} | ||||
|         {% for css in yml['css']['item'] %} | ||||
|         <link href="{{ css }}" rel="stylesheet"> | ||||
|         {% endfor %} | ||||
| 	{% endif %} | ||||
| 	{% if yml['js']['head'] %} | ||||
|         {% for js in yml['js']['head'] %} | ||||
|         <script src="{{ js }}" ></script> | ||||
|         {% endfor %} | ||||
| 	{% endif %} | ||||
|        {{ yml['header'] | safe }} | ||||
|        {% if yml['css']['item'] %} | ||||
|          {% for css in yml['css']['item'] %} | ||||
|          <link href="{{ css }}" rel="stylesheet"> | ||||
|          {% endfor %} | ||||
|         {% endif %} | ||||
|         {% if yml['js']['head'] %} | ||||
|          {% for js in yml['js']['head'] %} | ||||
|          <script src="{{ js }}" ></script> | ||||
|          {% endfor %} | ||||
|         {% endif %} | ||||
| 
 | ||||
| 	<title>EnglishPal Study Room for {{username}}</title> | ||||
|        <title>EnglishPal Study Room for {{username}}</title> | ||||
|     </head> | ||||
|     <body> | ||||
| 	<div class="container-fluid"> | ||||
| 	    <p class="mt-md-3"> | ||||
| 		<input type="button" id="btn-cancel-selection" value="取消勾选" onclick="toggleCheckboxSelection(false)" /> | ||||
| 		<input type="button" id="btn-selection" value="全部勾选" onclick="toggleCheckboxSelection(true)" /> | ||||
| 	    </p> | ||||
| 	    <form method="post" action="/{{username}}/mark"> | ||||
| 		<button type="submit" name="add-btn" class="btn btn-outline-primary btn-lg">加入我的生词簿</button> | ||||
| 		{% for x in lst %} | ||||
| 		{% set word = x[0]%} | ||||
| 		<p> | ||||
| 		    <font color="grey">{{loop.index}}</font> | ||||
| 		    : | ||||
| 		    <a href='http://youdao.com/w/eng/{{word}}/#keyfrom=dict2.index' title={{word}}>{{word}}</a> | ||||
| 		    ({{x[1]}}) | ||||
| 		    <input type="checkbox" name="marked" value="{{word}}" checked> | ||||
| 		</p> | ||||
|       <div class="container-fluid"> | ||||
|           <p class="mt-md-3"> | ||||
|                <input type="button" id="btn-cancel-selection" value="取消勾选" onclick="toggleCheckboxSelection(false)" /> | ||||
|                <input type="button" id="btn-selection" value="全部勾选" onclick="toggleCheckboxSelection(true)" /> | ||||
|           </p> | ||||
|           <form method="post" action="/{{username}}/mark"> | ||||
|               <button type="submit" name="add-btn" class="btn btn-outline-primary btn-lg" onclick="clearSelectedWords()">加入我的生词簿</button> | ||||
|               {% for x in lst %} | ||||
|               {% set word = x[0]%} | ||||
|               <p> | ||||
|                     <font color="grey">{{loop.index}}</font> | ||||
|                     : | ||||
|                     <a href='http://youdao.com/w/eng/{{word}}/#keyfrom=dict2.index' title={{word}}>{{word}}</a> | ||||
|                     ({{x[1]}}) | ||||
|                     <input type="checkbox" name="marked" value="{{word}}" checked> | ||||
|               </p> | ||||
| 
 | ||||
| 		{% endfor %} | ||||
| 	    </form> | ||||
| 	    {{ yml['footer'] | safe }} | ||||
| 	    {% if yml['js']['bottom'] %} | ||||
|                {% endfor %} | ||||
|            </form> | ||||
|            {{ yml['footer'] | safe }} | ||||
|            {% if yml['js']['bottom'] %} | ||||
|             {% for js in yml['js']['bottom'] %} | ||||
|             <script src="{{ js }}" ></script> | ||||
|              <script src="{{ js }}" ></script> | ||||
|             {% endfor %} | ||||
| 	    {% endif %} | ||||
| 	</div> | ||||
|         {% endif %} | ||||
|       </div> | ||||
|     </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -0,0 +1,98 @@ | |||
| import random | ||||
| import string | ||||
| import time | ||||
| 
 | ||||
| from selenium import webdriver | ||||
| from selenium.webdriver.support.wait import WebDriverWait | ||||
| from selenium.webdriver.support import expected_conditions as EC | ||||
| 
 | ||||
| HOME_PAGE = "http://127.0.0.1:5000/" | ||||
| 
 | ||||
| word = [] | ||||
| uname = 'lanhui' | ||||
| password = 'l0ve1t' | ||||
| def has_punctuation(s):  #用于检查单词是否包含标点符号 | ||||
|     return [c for c in s if c in string.punctuation] != [] | ||||
| 
 | ||||
| def login(driver): | ||||
|     driver.get(HOME_PAGE) | ||||
|     assert 'English Pal - Learn English smartly!' in driver.page_source | ||||
|     # 登录 | ||||
|     login_elem = driver.find_element_by_link_text('登录') | ||||
|     login_elem.click() | ||||
| 
 | ||||
|     username_input = driver.find_element_by_id('username') | ||||
|     username_input.send_keys(uname) | ||||
| 
 | ||||
|     password_input = driver.find_element_by_id('password') | ||||
|     password_input.send_keys(password) | ||||
| 
 | ||||
|     login_btn = driver.find_element_by_xpath('//button[text()="登录"]')  # 找到登录按钮 | ||||
|     login_btn.click() | ||||
| 
 | ||||
|     # 确保页面加载完 | ||||
|     try: | ||||
|         WebDriverWait(driver, 10).until( | ||||
|             EC.title_is("EnglishPal Study Room for " + uname)  # 替换为实际的页面标题 | ||||
|         ) | ||||
|     except Exception as e: | ||||
|         print("页面加载失败:", e) | ||||
|         driver.quit() | ||||
|         exit() | ||||
|     assert 'EnglishPal Study Room for ' + uname in driver.title | ||||
| 
 | ||||
| def test_save_selected_word(): | ||||
|     global word | ||||
|     # 调用本地chromedriver | ||||
|     driver = webdriver.Chrome(executable_path="C:\Program Files\Google\Chrome\Application\chromedriver.exe") | ||||
|     try: | ||||
|         login(driver) | ||||
|         #点击单词添加到已选单词列表 | ||||
|         # 获取文章内容 | ||||
|         elem = driver.find_element_by_id('text-content') | ||||
|         essay_content = elem.text | ||||
| 
 | ||||
|         #随机选择单词 长度不小于6个字符,并且不包含标点符号 | ||||
|         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()) | ||||
|         print(type(word))  #str | ||||
|         elem.send_keys(word) #单词输入到输入框 | ||||
| 
 | ||||
|         # 检查单词是否已成功添加到已选列表 | ||||
|         # 再次获取<textarea>中的文本内容,以确认单词已被输入 | ||||
|         updated_textarea_content = elem.get_attribute('value') | ||||
|         # 检查<textarea>中的内容是否包含输入的单词 | ||||
|         assert word == updated_textarea_content | ||||
|         # 检查是否保存到 localStorage | ||||
|         stored_words = driver.execute_script('return localStorage.getItem("selectedWords");') | ||||
|         assert word == stored_words | ||||
|         #检查退出登录、关闭web页面后是否保存已选单词 | ||||
|         # 退出登录 | ||||
|         elem = driver.find_element_by_link_text('退出') | ||||
|         elem.click() | ||||
| 
 | ||||
|         # 关闭当前标签页 | ||||
|         driver.execute_script("window.open('');window.close();") | ||||
| 
 | ||||
|         # 等待一会儿,让浏览器有足够的时间关闭标签页 | ||||
|         time.sleep(2) | ||||
| 
 | ||||
|         # 重新打开一个新的标签页 | ||||
|         driver.execute_script("window.open('');") | ||||
|         driver.switch_to.window(driver.window_handles[-1])  # 切换到新打开的标签页 | ||||
| 
 | ||||
|         login(driver) | ||||
|         elem = driver.find_element_by_id('selected-words') | ||||
|         textarea_content = elem.get_attribute('value') | ||||
|         print(f'word:{word}') | ||||
|         print(f'selected:{textarea_content}') | ||||
|         assert word == textarea_content | ||||
|     except Exception as e: | ||||
|         print("An error occurred:", e) | ||||
|     finally: | ||||
|         # 关闭浏览器 | ||||
|         driver.quit() | ||||
| 
 | ||||
| test_save_selected_word() | ||||
		Loading…
	
		Reference in New Issue