i18n-language-switching.cy.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import { mockI18nSuccess, mockAllRequiredAPIs } from '../../support/mock/handlers/i18n';
  2. import LoginPage from '../../support/pageObjects/LoginPage';
  3. describe('多语言资源语言切换测试', () => {
  4. const loginPage = new LoginPage();
  5. beforeEach(() => {
  6. cy.clearAllSessionStorage();
  7. cy.clearAllLocalStorage();
  8. // Mock所有必要的API,避免影响页面加载
  9. mockAllRequiredAPIs();
  10. });
  11. it('从中文切换到英文', () => {
  12. // 首先加载中文
  13. mockI18nSuccess('zh');
  14. cy.window().then((win) => {
  15. Object.defineProperty(win.navigator, 'language', {
  16. value: 'zh-CN',
  17. writable: false
  18. });
  19. });
  20. loginPage.visit();
  21. cy.wait('@getI18nZHSuccess');
  22. // 验证中文内容显示
  23. cy.get('body').should('contain', '患者管理');
  24. // 验证Redux状态为中文
  25. cy.window().its('store').invoke('getState').then((state) => {
  26. expect(state.i18n.currentLocale).to.equal('zh');
  27. expect(state.i18n.messages).to.have.property('patient', '患者管理');
  28. });
  29. // 模拟语言切换 - 重新访问页面并设置英文语言
  30. mockI18nSuccess('en');
  31. cy.window().then((win) => {
  32. Object.defineProperty(win.navigator, 'language', {
  33. value: 'en-US',
  34. writable: false
  35. });
  36. });
  37. loginPage.visit();
  38. cy.wait('@getI18nENSuccess');
  39. // 验证英文内容显示
  40. cy.get('body').should('contain', 'Patient Management');
  41. // 验证Redux状态为英文
  42. cy.window().its('store').invoke('getState').then((state) => {
  43. expect(state.i18n.currentLocale).to.equal('en');
  44. expect(state.i18n.messages).to.have.property('patient', 'Patient Management');
  45. });
  46. });
  47. it('从英文切换到中文', () => {
  48. // 首先加载英文
  49. mockI18nSuccess('en');
  50. cy.window().then((win) => {
  51. Object.defineProperty(win.navigator, 'language', {
  52. value: 'en-US',
  53. writable: false
  54. });
  55. });
  56. loginPage.visit();
  57. cy.wait('@getI18nENSuccess');
  58. // 验证英文内容显示
  59. cy.get('body').should('contain', 'Patient Management');
  60. // 模拟语言切换到中文
  61. mockI18nSuccess('zh');
  62. cy.window().then((win) => {
  63. Object.defineProperty(win.navigator, 'language', {
  64. value: 'zh-CN',
  65. writable: false
  66. });
  67. });
  68. loginPage.visit();
  69. cy.wait('@getI18nZHSuccess');
  70. // 验证中文内容显示
  71. cy.get('body').should('contain', '患者管理');
  72. // 验证Redux状态正确更新
  73. cy.window().its('store').invoke('getState').then((state) => {
  74. expect(state.i18n.currentLocale).to.equal('zh');
  75. expect(state.i18n.messages).to.have.property('patient', '患者管理');
  76. });
  77. });
  78. it('验证不同地区变体的语言检测', () => {
  79. const testCases = [
  80. // 中文变体都应该加载中文资源
  81. { browserLang: 'zh', expectedLocale: 'zh', expectedText: '患者管理' },
  82. { browserLang: 'zh-CN', expectedLocale: 'zh', expectedText: '患者管理' },
  83. { browserLang: 'zh-TW', expectedLocale: 'zh', expectedText: '患者管理' },
  84. { browserLang: 'zh-HK', expectedLocale: 'zh', expectedText: '患者管理' },
  85. { browserLang: 'zh-SG', expectedLocale: 'zh', expectedText: '患者管理' },
  86. // 英文变体都应该加载英文资源
  87. { browserLang: 'en', expectedLocale: 'en', expectedText: 'Patient Management' },
  88. { browserLang: 'en-US', expectedLocale: 'en', expectedText: 'Patient Management' },
  89. { browserLang: 'en-GB', expectedLocale: 'en', expectedText: 'Patient Management' },
  90. { browserLang: 'en-AU', expectedLocale: 'en', expectedText: 'Patient Management' },
  91. { browserLang: 'en-CA', expectedLocale: 'en', expectedText: 'Patient Management' }
  92. ];
  93. testCases.forEach(({ browserLang, expectedLocale, expectedText }, index) => {
  94. mockI18nSuccess(expectedLocale as 'zh' | 'en');
  95. cy.window().then((win) => {
  96. Object.defineProperty(win.navigator, 'language', {
  97. value: browserLang,
  98. writable: false
  99. });
  100. });
  101. loginPage.visit();
  102. cy.wait(`@getI18n${expectedLocale.toUpperCase()}Success`);
  103. // 验证正确的语言内容显示
  104. cy.get('body').should('contain', expectedText);
  105. // 验证Redux状态
  106. cy.window().its('store').invoke('getState').then((state) => {
  107. expect(state.i18n.currentLocale).to.equal(expectedLocale);
  108. });
  109. // 清理,准备下一个测试
  110. if (index < testCases.length - 1) {
  111. cy.clearAllSessionStorage();
  112. cy.clearAllLocalStorage();
  113. }
  114. });
  115. });
  116. it('验证语言切换时的加载状态', () => {
  117. // 首先加载中文
  118. mockI18nSuccess('zh');
  119. cy.window().then((win) => {
  120. Object.defineProperty(win.navigator, 'language', {
  121. value: 'zh-CN',
  122. writable: false
  123. });
  124. });
  125. loginPage.visit();
  126. cy.wait('@getI18nZHSuccess');
  127. cy.get('body').should('contain', '患者管理');
  128. // 切换到英文,验证加载过程
  129. mockI18nSuccess('en');
  130. cy.window().then((win) => {
  131. Object.defineProperty(win.navigator, 'language', {
  132. value: 'en-US',
  133. writable: false
  134. });
  135. });
  136. loginPage.visit();
  137. // 验证加载状态显示
  138. cy.contains('加载多语言资源中...').should('be.visible');
  139. // 等待加载完成
  140. cy.wait('@getI18nENSuccess');
  141. // 验证加载状态消失,新语言内容显示
  142. cy.contains('加载多语言资源中...').should('not.exist');
  143. cy.get('body').should('contain', 'Patient Management');
  144. });
  145. it('验证语言切换时Redux状态的完整性', () => {
  146. // 加载中文
  147. mockI18nSuccess('zh');
  148. cy.window().then((win) => {
  149. Object.defineProperty(win.navigator, 'language', {
  150. value: 'zh-CN',
  151. writable: false
  152. });
  153. });
  154. loginPage.visit();
  155. cy.wait('@getI18nZHSuccess');
  156. // 验证中文状态
  157. cy.window().its('store').invoke('getState').then((state) => {
  158. expect(state.i18n.currentLocale).to.equal('zh');
  159. expect(state.i18n.loading).to.be.false;
  160. expect(state.i18n.error).to.be.null;
  161. expect(state.i18n.messages).to.have.property('register', '注册');
  162. expect(state.i18n.messages).to.have.property('worklist', '任务清单');
  163. });
  164. // 切换到英文
  165. mockI18nSuccess('en');
  166. cy.window().then((win) => {
  167. Object.defineProperty(win.navigator, 'language', {
  168. value: 'en-US',
  169. writable: false
  170. });
  171. });
  172. loginPage.visit();
  173. cy.wait('@getI18nENSuccess');
  174. // 验证英文状态完全替换了中文状态
  175. cy.window().its('store').invoke('getState').then((state) => {
  176. expect(state.i18n.currentLocale).to.equal('en');
  177. expect(state.i18n.loading).to.be.false;
  178. expect(state.i18n.error).to.be.null;
  179. expect(state.i18n.messages).to.have.property('register', 'Register');
  180. expect(state.i18n.messages).to.have.property('worklist', 'Task List');
  181. // 确保中文内容已被替换
  182. expect(state.i18n.messages.register).to.not.equal('注册');
  183. expect(state.i18n.messages.worklist).to.not.equal('任务清单');
  184. });
  185. });
  186. it('验证快速语言切换的稳定性', () => {
  187. // 快速切换多次语言,验证系统稳定性
  188. const switchSequence = [
  189. { lang: 'zh-CN', locale: 'zh', text: '患者管理' },
  190. { lang: 'en-US', locale: 'en', text: 'Patient Management' },
  191. { lang: 'zh-TW', locale: 'zh', text: '患者管理' },
  192. { lang: 'en-GB', locale: 'en', text: 'Patient Management' },
  193. { lang: 'zh-CN', locale: 'zh', text: '患者管理' }
  194. ];
  195. switchSequence.forEach(({ lang, locale, text }, index) => {
  196. mockI18nSuccess(locale as 'zh' | 'en');
  197. cy.window().then((win) => {
  198. Object.defineProperty(win.navigator, 'language', {
  199. value: lang,
  200. writable: false
  201. });
  202. });
  203. loginPage.visit();
  204. cy.wait(`@getI18n${locale.toUpperCase()}Success`);
  205. cy.get('body').should('contain', text);
  206. // 验证每次切换后状态都正确
  207. cy.window().its('store').invoke('getState').then((state) => {
  208. expect(state.i18n.currentLocale).to.equal(locale);
  209. expect(state.i18n.loading).to.be.false;
  210. expect(state.i18n.error).to.be.null;
  211. });
  212. });
  213. });
  214. });