login-i18n.cy.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. import { mockI18nSuccess, mockAllRequiredAPIs } from '../../support/mock/handlers/i18n';
  2. import { mockLoginSuccess, mockLoginFail } from '../../support/mock/handlers/user';
  3. import LoginPage from '../../support/pageObjects/LoginPage';
  4. describe('Login Page - I18n Display Test', () => {
  5. const loginPage = new LoginPage();
  6. beforeEach(() => {
  7. cy.clearAllSessionStorage();
  8. cy.clearAllLocalStorage();
  9. mockAllRequiredAPIs();
  10. });
  11. describe('中文显示测试', () => {
  12. it('应该正确显示中文登录页面', () => {
  13. // Mock 中文多语言资源
  14. mockI18nSuccess('zh_CN');
  15. mockAllRequiredAPIs('zh_CN');
  16. // 设置浏览器语言为中文
  17. cy.window().then((win) => {
  18. Object.defineProperty(win.navigator, 'language', {
  19. value: 'zh-CN',
  20. writable: false
  21. });
  22. });
  23. // 访问登录页面
  24. loginPage.visit();
  25. // 等待多语言资源加载完成
  26. cy.wait('@getI18nZH_CNSuccess');
  27. // 验证所有文本元素显示为中文
  28. loginPage.verifyLanguage('zh');
  29. // 验证输入框占位符为中文
  30. loginPage.verifyPlaceholders('zh');
  31. // 验证页面上所有中文文本存在
  32. cy.get('body').should('contain', '用户名');
  33. cy.get('body').should('contain', '密码');
  34. cy.get('body').should('contain', '登录');
  35. cy.get('body').should('contain', '急诊');
  36. });
  37. it('应该显示中文的表单验证消息', () => {
  38. mockI18nSuccess('zh_CN');
  39. mockAllRequiredAPIs('zh_CN');
  40. cy.window().then((win) => {
  41. Object.defineProperty(win.navigator, 'language', {
  42. value: 'zh-CN',
  43. writable: false
  44. });
  45. });
  46. loginPage.visit();
  47. cy.wait('@getI18nZH_CNSuccess');
  48. // 不输入任何内容,直接点击登录按钮
  49. loginPage.getLoginButton().click();
  50. // 验证中文验证消息显示
  51. cy.contains('请输入用户名').should('be.visible');
  52. });
  53. it('应该显示中文的登录成功消息', () => {
  54. mockI18nSuccess('zh_CN');
  55. mockAllRequiredAPIs('zh_CN');
  56. mockLoginSuccess();
  57. cy.window().then((win) => {
  58. Object.defineProperty(win.navigator, 'language', {
  59. value: 'zh-CN',
  60. writable: false
  61. });
  62. });
  63. loginPage.visit();
  64. cy.wait('@getI18nZH_CNSuccess');
  65. // 执行登录
  66. loginPage.login('admin', '123456');
  67. cy.wait('@loginSuccess');
  68. // 验证中文成功消息
  69. cy.contains('登录成功').should('be.visible', { timeout: 10000 });
  70. });
  71. it('应该显示中文的登录失败消息', () => {
  72. mockI18nSuccess('zh_CN');
  73. mockAllRequiredAPIs('zh_CN');
  74. mockLoginFail();
  75. cy.window().then((win) => {
  76. Object.defineProperty(win.navigator, 'language', {
  77. value: 'zh-CN',
  78. writable: false
  79. });
  80. });
  81. loginPage.visit();
  82. cy.wait('@getI18nZH_CNSuccess');
  83. // 执行登录
  84. loginPage.login('wronguser', 'wrongpassword');
  85. cy.wait('@loginFail');
  86. // 验证中文失败消息
  87. cy.contains('登录失败').should('be.visible', { timeout: 10000 });
  88. });
  89. });
  90. describe('英文显示测试', () => {
  91. it('应该正确显示英文登录页面', () => {
  92. // Mock 英文多语言资源
  93. mockI18nSuccess('en_US');
  94. mockAllRequiredAPIs('en_US');
  95. // 设置浏览器语言为英文
  96. cy.window().then((win) => {
  97. Object.defineProperty(win.navigator, 'language', {
  98. value: 'en-US',
  99. writable: false
  100. });
  101. });
  102. // 访问登录页面
  103. loginPage.visit();
  104. // 等待多语言资源加载完成
  105. cy.wait('@getI18nEN_USSuccess');
  106. // 验证所有文本元素显示为英文
  107. loginPage.verifyLanguage('en');
  108. // 验证输入框占位符为英文
  109. loginPage.verifyPlaceholders('en');
  110. // 验证页面上所有英文文本存在
  111. cy.get('body').should('contain', 'Username');
  112. cy.get('body').should('contain', 'Password');
  113. cy.get('body').should('contain', 'Login');
  114. cy.get('body').should('contain', 'Emergency');
  115. });
  116. it('应该显示英文的表单验证消息', () => {
  117. mockI18nSuccess('en_US');
  118. mockAllRequiredAPIs('en_US');
  119. cy.window().then((win) => {
  120. Object.defineProperty(win.navigator, 'language', {
  121. value: 'en-US',
  122. writable: false
  123. });
  124. });
  125. loginPage.visit();
  126. cy.wait('@getI18nEN_USSuccess');
  127. // 不输入任何内容,直接点击登录按钮
  128. loginPage.getLoginButton().click();
  129. // 验证英文验证消息显示
  130. cy.contains('Please enter username').should('be.visible');
  131. });
  132. it('应该显示英文的登录成功消息', () => {
  133. mockI18nSuccess('en_US');
  134. mockAllRequiredAPIs('en_US');
  135. mockLoginSuccess();
  136. cy.window().then((win) => {
  137. Object.defineProperty(win.navigator, 'language', {
  138. value: 'en-US',
  139. writable: false
  140. });
  141. });
  142. loginPage.visit();
  143. cy.wait('@getI18nEN_USSuccess');
  144. // 执行登录
  145. loginPage.login('admin', '123456');
  146. cy.wait('@loginSuccess');
  147. // 验证英文成功消息
  148. cy.contains('Login successful').should('be.visible', { timeout: 10000 });
  149. });
  150. it('应该显示英文的登录失败消息', () => {
  151. mockI18nSuccess('en_US');
  152. mockAllRequiredAPIs('en_US');
  153. mockLoginFail();
  154. cy.window().then((win) => {
  155. Object.defineProperty(win.navigator, 'language', {
  156. value: 'en-US',
  157. writable: false
  158. });
  159. });
  160. loginPage.visit();
  161. cy.wait('@getI18nEN_USSuccess');
  162. // 执行登录
  163. loginPage.login('wronguser', 'wrongpassword');
  164. cy.wait('@loginFail');
  165. // 验证英文失败消息
  166. cy.contains('Login failed').should('be.visible', { timeout: 10000 });
  167. });
  168. });
  169. describe('语言切换测试', () => {
  170. it('应该能从中文切换到英文', () => {
  171. // 首先加载中文
  172. mockI18nSuccess('zh_CN');
  173. mockAllRequiredAPIs('zh_CN');
  174. cy.window().then((win) => {
  175. Object.defineProperty(win.navigator, 'language', {
  176. value: 'zh-CN',
  177. writable: false
  178. });
  179. });
  180. loginPage.visit();
  181. cy.wait('@getI18nZH_CNSuccess');
  182. // 验证中文显示
  183. loginPage.verifyLanguage('zh');
  184. // 切换到英文
  185. mockI18nSuccess('en_US');
  186. mockAllRequiredAPIs('en_US');
  187. cy.window().then((win) => {
  188. Object.defineProperty(win.navigator, 'language', {
  189. value: 'en-US',
  190. writable: false
  191. });
  192. });
  193. loginPage.visit();
  194. cy.wait('@getI18nEN_USSuccess');
  195. // 验证英文显示
  196. loginPage.verifyLanguage('en');
  197. });
  198. it('应该能从英文切换到中文', () => {
  199. // 首先加载英文
  200. mockI18nSuccess('en_US');
  201. mockAllRequiredAPIs('en_US');
  202. cy.window().then((win) => {
  203. Object.defineProperty(win.navigator, 'language', {
  204. value: 'en-US',
  205. writable: false
  206. });
  207. });
  208. loginPage.visit();
  209. cy.wait('@getI18nEN_USSuccess');
  210. // 验证英文显示
  211. loginPage.verifyLanguage('en');
  212. // 切换到中文
  213. mockI18nSuccess('zh_CN');
  214. mockAllRequiredAPIs('zh_CN');
  215. cy.window().then((win) => {
  216. Object.defineProperty(win.navigator, 'language', {
  217. value: 'zh-CN',
  218. writable: false
  219. });
  220. });
  221. loginPage.visit();
  222. cy.wait('@getI18nZH_CNSuccess');
  223. // 验证中文显示
  224. loginPage.verifyLanguage('zh');
  225. });
  226. });
  227. describe('Redux 状态验证', () => {
  228. it('中文模式下 Redux 状态应该正确', () => {
  229. mockI18nSuccess('zh_CN');
  230. mockAllRequiredAPIs('zh_CN');
  231. cy.window().then((win) => {
  232. Object.defineProperty(win.navigator, 'language', {
  233. value: 'zh-CN',
  234. writable: false
  235. });
  236. });
  237. loginPage.visit();
  238. cy.wait('@getI18nZH_CNSuccess');
  239. // 验证 Redux 状态
  240. cy.window().its('store').invoke('getState').then((state) => {
  241. expect(state.i18n.currentLocale).to.equal('zh_CN');
  242. expect(state.i18n.loading).to.be.false;
  243. expect(state.i18n.error).to.be.null;
  244. expect(state.i18n.messages).to.have.property('login.username', '用户名');
  245. expect(state.i18n.messages).to.have.property('login.password', '密码');
  246. expect(state.i18n.messages).to.have.property('login.submit', '登录');
  247. expect(state.i18n.messages).to.have.property('login.emergency', '急诊');
  248. });
  249. });
  250. it('英文模式下 Redux 状态应该正确', () => {
  251. mockI18nSuccess('en_US');
  252. mockAllRequiredAPIs('en_US');
  253. cy.window().then((win) => {
  254. Object.defineProperty(win.navigator, 'language', {
  255. value: 'en-US',
  256. writable: false
  257. });
  258. });
  259. loginPage.visit();
  260. cy.wait('@getI18nEN_USSuccess');
  261. // 验证 Redux 状态
  262. cy.window().its('store').invoke('getState').then((state) => {
  263. expect(state.i18n.currentLocale).to.equal('en_US');
  264. expect(state.i18n.loading).to.be.false;
  265. expect(state.i18n.error).to.be.null;
  266. expect(state.i18n.messages).to.have.property('login.username', 'Username');
  267. expect(state.i18n.messages).to.have.property('login.password', 'Password');
  268. expect(state.i18n.messages).to.have.property('login.submit', 'Login');
  269. expect(state.i18n.messages).to.have.property('login.emergency', 'Emergency');
  270. });
  271. });
  272. });
  273. describe('视觉验证(手动查看)', () => {
  274. it('[视觉] 中文登录页面完整显示', () => {
  275. mockI18nSuccess('zh_CN');
  276. mockAllRequiredAPIs('zh_CN');
  277. cy.window().then((win) => {
  278. Object.defineProperty(win.navigator, 'language', {
  279. value: 'zh-CN',
  280. writable: false
  281. });
  282. });
  283. loginPage.visit();
  284. cy.wait('@getI18nZH_CNSuccess');
  285. // 等待页面完全加载
  286. loginPage.getUsernameInput().should('be.visible');
  287. loginPage.getPasswordInput().should('be.visible');
  288. loginPage.getLoginButton().should('be.visible');
  289. loginPage.getEmergencyButton().should('be.visible');
  290. // 添加等待时间供手动查看
  291. cy.wait(500);
  292. });
  293. it('[视觉] 英文登录页面完整显示', () => {
  294. mockI18nSuccess('en_US');
  295. mockAllRequiredAPIs('en_US');
  296. cy.window().then((win) => {
  297. Object.defineProperty(win.navigator, 'language', {
  298. value: 'en-US',
  299. writable: false
  300. });
  301. });
  302. loginPage.visit();
  303. cy.wait('@getI18nEN_USSuccess');
  304. // 等待页面完全加载
  305. loginPage.getUsernameInput().should('be.visible');
  306. loginPage.getPasswordInput().should('be.visible');
  307. loginPage.getLoginButton().should('be.visible');
  308. loginPage.getEmergencyButton().should('be.visible');
  309. // 添加等待时间供手动查看
  310. cy.wait(500);
  311. });
  312. });
  313. });