forked from mrlan/EnglishPal
				
			Merge branch 'Alpha-snapshot20230621' into Bug551-DingZeYu
						commit
						c9c0ef60d8
					
				|  | @ -150,6 +150,8 @@ Run English Pal first, then run the test using pytest as follows: pytest --html= | |||
| 
 | ||||
| The above command will generate a HTML report file pytest_report.html after finishing executing test_add_word.py.  Note: you need to install pytest-html package first: pip install pytest-html. | ||||
| 
 | ||||
| You may also want to use [webdriver-manager](https://pypi.org/project/webdriver-manager/) from PyPI, so that you can avoid tediously installing a web driver executable manually.  However, my experience shows that webdriver-manager is too slow.  For example, it took me 16 minutes to run 9 tests, while with the pre-installed web driver executable, it took less than 2 minutes. | ||||
| 
 | ||||
| ## TODO | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| let isRead = true; | ||||
| let isChoose = true; | ||||
| // initialize from localStorage
 | ||||
| let isRead = localStorage.getItem('readChecked') !== 'false';  // default to true
 | ||||
| let isChoose = localStorage.getItem('chooseChecked') !== 'false'; | ||||
| 
 | ||||
| function getWord() { | ||||
|     return window.getSelection ? window.getSelection() : document.selection.createRange().text; | ||||
|  | @ -11,6 +12,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,13 +26,15 @@ inputSlider.oninput = () => { | |||
| 
 | ||||
| function onReadClick() { | ||||
|     isRead = !isRead; | ||||
|     localStorage.setItem('readChecked', isRead); | ||||
| } | ||||
| 
 | ||||
| function onChooseClick() { | ||||
|     isChoose = !isChoose; | ||||
|     localStorage.setItem('chooseChecked', isChoose); | ||||
| } | ||||
| 
 | ||||
| // 如果网页刷新,停止播放声音
 | ||||
| if (performance.getEntriesByType("navigation")[0].type == "reload") { | ||||
|     Reader.stopRead(); | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| let isHighlight = true; | ||||
| let isHighlight = localStorage.getItem('highlightChecked') !== 'false'; // default to true
 | ||||
| 
 | ||||
| function cancelBtnHandler() { | ||||
|     cancelHighlighting(); | ||||
|  | @ -39,7 +39,7 @@ function highLight() { | |||
|             } | ||||
|             totalSet = new Set([...totalSet, ...matches]); | ||||
|         } | ||||
|     }  | ||||
|     } | ||||
|     // 删除所有的mark标签,防止标签发生嵌套
 | ||||
|     articleContent = articleContent.replace(/<(mark)[^>]*>/gi, ""); | ||||
|     articleContent = articleContent.replace(/<(\/mark)[^>]*>/gi, ""); | ||||
|  | @ -74,6 +74,7 @@ function toggleHighlighting() { | |||
|         isHighlight = true; | ||||
|         highLight(); | ||||
|     } | ||||
|      localStorage.setItem('highlightChecked', isHighlight); | ||||
| } | ||||
| 
 | ||||
| showBtnHandler(); | ||||
|  | @ -15,6 +15,10 @@ | |||
|             alert('输入不能为空!'); | ||||
|             return false; | ||||
|         } | ||||
|         if (password.includes(' ')) { | ||||
|             alert('输入不能包含空格!'); | ||||
|             return false; | ||||
|         } | ||||
|         $.post( | ||||
|             "/login", {'username': username, 'password': password}, | ||||
|             function (response) { | ||||
|  |  | |||
|  | @ -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,22 @@ | |||
|             <script src="{{ js }}" ></script> | ||||
|         {% endfor %} | ||||
|     {% endif %} | ||||
| <script type="text/javascript"> | ||||
|     // IIFE, avoid polluting the global scope | ||||
|     (function() { | ||||
|         const articleInput = document.querySelector('#article'); | ||||
|         articleInput.value = localStorage.getItem('article') || ''; | ||||
| 
 | ||||
|         articleInput.addEventListener('input', function() { | ||||
|             localStorage.setItem('article', articleInput.value); | ||||
|         }); | ||||
| 
 | ||||
|         window.clearArticle = function() { | ||||
|             localStorage.removeItem('article'); | ||||
|             articleInput.value = ''; | ||||
|         }; | ||||
|     })(); | ||||
| 
 | ||||
| </script> | ||||
| </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ | |||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <title>Title</title> | ||||
|     <title>单词词频</title> | ||||
| 
 | ||||
|     {{ yml['header'] | safe }} | ||||
|     {% if yml['css']['item'] %} | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -16,6 +16,10 @@ You're logged in already! <a href="/logout">Logout</a>. | |||
|                 alert('输入不能为空!'); | ||||
|                 return false; | ||||
|             } | ||||
|             if (password.includes(' ') || password2.includes(' ')) { | ||||
|                 alert('输入不能包含空格!'); | ||||
|                 return false; | ||||
|             } | ||||
|             if (password !== password2) { | ||||
|                 alert('确认密码与输入密码不一致!'); | ||||
|                 return false; | ||||
|  |  | |||
|  | @ -86,7 +86,7 @@ | |||
|             <div> | ||||
|                 <p><small class="text-muted" id="source">{{ today_article['source'] }}</small></p><br/> | ||||
|             </div> | ||||
|              | ||||
| 
 | ||||
|             <p><b id="question">{{ today_article['question'] }}</b></p><br/> | ||||
|                 <script type="text/javascript"> | ||||
|                     function toggle_visibility(id) { {# https://css-tricks.com/snippets/javascript/showhide-element/#} | ||||
|  | @ -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" /> | ||||
|         </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"> | ||||
|  | @ -139,7 +139,7 @@ | |||
| 
 | ||||
|     {% if d_len > 0 %} | ||||
|         <p> | ||||
|             <b>我的生词簿</b>  | ||||
|             <b>我的生词簿</b> | ||||
|             <label for="move_dynamiclly"> | ||||
|                 <input type="checkbox" name="move_dynamiclly" id="move_dynamiclly" checked> | ||||
|                 允许动态调整顺序 | ||||
|  | @ -174,11 +174,54 @@ | |||
| {% endif %} | ||||
| <script type="text/javascript"> | ||||
|     window.onload = function () { // 页面加载时执行 | ||||
|         const settings = { | ||||
|             // initialize settings from localStorage | ||||
|             highlightChecked: localStorage.getItem('highlightChecked') !== 'false', // localStorage stores strings, default to true. same below | ||||
|             readChecked: localStorage.getItem('readChecked') !== 'false', | ||||
|             chooseChecked: localStorage.getItem('chooseChecked') !== 'false', | ||||
|             rangeValue: localStorage.getItem('rangeValue') || '1', | ||||
|             selectedWords: localStorage.getItem('selectedWords') || '' | ||||
|         }; | ||||
| 
 | ||||
|         const elements = { | ||||
|             highlightCheckbox: document.querySelector('#highlightCheckbox'), | ||||
|             readCheckbox: document.querySelector('#readCheckbox'), | ||||
|             chooseCheckbox: document.querySelector('#chooseCheckbox'), | ||||
|             rangeComponent: document.querySelector('#rangeComponent'), | ||||
|             rangeValueDisplay: document.querySelector('#rangeValue'), | ||||
|             selectedWordsInput: document.querySelector('#selected-words') | ||||
|         }; | ||||
|         // 应用设置到页面元素 | ||||
|         elements.highlightCheckbox.checked = settings.highlightChecked; | ||||
|         elements.readCheckbox.checked = settings.readChecked; | ||||
|         elements.chooseCheckbox.checked = settings.chooseChecked; | ||||
|         elements.rangeComponent.value = settings.rangeValue; | ||||
|         elements.rangeValueDisplay.textContent = `${settings.rangeValue}x`; | ||||
|         elements.selectedWordsInput.value = settings.selectedWords; | ||||
| 
 | ||||
|         // 刷新页面或进入页面时判断,若不是首篇文章,则上一篇按钮可见 | ||||
|         if(sessionStorage.getItem('pre_page_button')!="display" && sessionStorage.getItem('pre_page_button')){ | ||||
|         if (sessionStorage.getItem('pre_page_button') !== 'display' && sessionStorage.getItem('pre_page_button')) { | ||||
|             $('#load_pre_article').show(); | ||||
|         } | ||||
|      }; | ||||
| 
 | ||||
|         // 事件监听器 | ||||
|         elements.selectedWordsInput.addEventListener('input', () => { | ||||
|             localStorage.setItem('selectedWords', elements.selectedWordsInput.value); | ||||
|         }); | ||||
| 
 | ||||
|         elements.rangeComponent.addEventListener('input', () => { | ||||
|             const rangeValue = elements.rangeComponent.value; | ||||
|             elements.rangeValueDisplay.textContent = `${rangeValue}x`; | ||||
|             localStorage.setItem('rangeValue', rangeValue); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     function clearSelectedWords() { | ||||
|         localStorage.removeItem('selectedWords'); | ||||
|         document.querySelector('#selected-words').value = ''; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     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> | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ import pytest | |||
| import sqlite3 | ||||
| import time | ||||
| from selenium import webdriver | ||||
| 
 | ||||
| from pathlib import Path | ||||
| 
 | ||||
| @pytest.fixture | ||||
|  | @ -11,7 +12,7 @@ def URL(): | |||
| 
 | ||||
| @pytest.fixture | ||||
| def driver(): | ||||
|     return webdriver.Edge()  # uncomment this line if you wish to run the test on your laptop | ||||
|     return webdriver.Edge()  # follow the "End-to-end testing" section in README.md to install the web driver executable | ||||
| 
 | ||||
| 
 | ||||
| @pytest.fixture | ||||
|  |  | |||
|  | @ -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)) | ||||
|  | @ -0,0 +1,53 @@ | |||
| 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 | ||||
| 
 | ||||
| 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() | ||||
|  | @ -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() | ||||
|  | @ -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'): | ||||
|  |  | |||
|  | @ -4,3 +4,5 @@ PyYAML~=6.0 | |||
| pony==0.7.16 | ||||
| snowballstemmer==2.2.0 | ||||
| Werkzeug==2.2.2 | ||||
| 
 | ||||
| pytest~=8.1.1 | ||||
		Loading…
	
		Reference in New Issue