فهرست منبع

test(exam,patient): add test code for read state to enable test environment access to examination;add data-testid attributes to navigation area buttons for testing

sw 1 ماه پیش
والد
کامیت
f071b8792a

+ 34 - 0
cypress.config.ts

@@ -1,10 +1,44 @@
 import { defineConfig } from 'cypress';
+import mqtt from 'mqtt'
+
+function logWithTimestamp(message, ...args) {
+  const timestamp = new Date().toLocaleString();
+  console.log(`[${timestamp}] ${message}`, ...args);
+  //cy.log(`[${timestamp}] ${message}`);
+}
 
 export default defineConfig({
+  viewportWidth: 1920,
+  viewportHeight: 1080,
   e2e: {
     baseUrl: 'http://localhost:10086/#/pages/index/index', // Adjust this to match your application's base URL
     // specPattern: '__e2e_test__/**/*.spec.ts',
     setupNodeEvents(on, config) {
+      on('task', {
+        // 参数:{ broker, topic, payload [, opts] }
+        mqttPublish({ broker = 'ws://localhost:8083/mqtt', topic, payload, qos = 0, retain = false }) {
+          return new Promise((resolve, reject) => {
+            console.log('这里执行了吗')
+            const client = mqtt.connect(broker)
+            client.on('connect', () => {
+              client.publish(topic, payload, { qos, retain }, err => {
+                // console.log(`发布数据--${payload}===broker:${broker}`)
+                logWithTimestamp(`发布数据--${payload}===broker:${broker}`)
+                // 关键:等底层 socket 的 buffer 清空
+                client.stream.on('drain', () => {
+                  client.end(true)   // true = 强制 flush 再关闭
+                  logWithTimestamp(`drain发布完成  topic : ${topic}`)
+                  resolve(null)
+                })
+                logWithTimestamp(`发布完成  topic : ${topic}`)
+                if (err) reject(err)
+                else resolve(null)
+              });
+            })
+            client.on('error', reject)
+          })
+        }
+      })
       return require('./cypress/plugins/index.js')(on, config);
     },
   },

+ 46 - 0
cypress/e2e/exam/device.ready.cy.ts

@@ -0,0 +1,46 @@
+import LoginPage from '../../support/pageObjects/LoginPage';
+import MainPage from '../../support/pageObjects/MainPage';
+import WorklistPage from '../../support/pageObjects/WorklistPage';
+
+
+describe('Exam Page Navigation', () => {
+  const loginPage = new LoginPage();
+  const mainPage = new MainPage();
+  const worklistPage = new WorklistPage();
+
+  beforeEach(() => {
+    loginPage.visit();
+    loginPage.getUsernameInput().should('be.visible');
+    loginPage.getPasswordInput().should('be.visible');
+    loginPage.getSubmitButton().should('be.visible');
+  });
+
+  it('应该检查到ready', () => {
+    loginPage.login('admin', '123456');
+    cy.contains('登录成功').should('be.visible', { timeout: 10000 });
+
+    //mainPage.clickExamButton();
+    // cy.url().should('include', '/exam');
+    //cy.wait(3000);
+    mainPage.clickPatientManagementButton();
+    mainPage.clickWorklistButton();
+    worklistPage.findTableAndDoubleClickFirstRow();
+    cy.wait(3000);
+    // mainPage.getHomeButton().click();
+    // cy.url().should('include', '/main');
+    cy.task('mqttPublish', {
+      broker: 'ws://192.168.1.60:8083/mqtt',
+      topic: 'MODULE/TASK/STATUS/GLOBAL',
+      payload: JSON.stringify({
+        GENStatus: "GENERATOR_STATUS_STANDBY",
+        GENReady: true,
+        FPDStatus: "DETECTOR_STATUS_STANDBY",
+        FPDReady: true,
+        InspStatus: "TASK_Ready",
+        InspReady: true,
+        AllReady: true
+      })
+    });
+    cy.get('button[data-testid="device-all-ready"]').should('have.class', 'text-green-500');
+  });
+});

+ 0 - 0
cypress/e2e/patient/worklist/enter_worklist.ts


+ 13 - 0
cypress/support/commands.js

@@ -25,3 +25,16 @@
 //
 // -- This will overwrite an existing command --
 // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+
+Cypress.Commands.add('logWithDate', (message, ...args) => {
+  const timestamp = new Date().toISOString();
+  const formattedMessage = `[${timestamp}] ${message}`;
+  
+  // 输出到控制台
+  console.log(formattedMessage, ...args);
+  
+  // 也可以输出到 Cypress 的命令日志(可选)
+  cy.log(formattedMessage);
+  
+  return null; // Cypress 命令需要返回 null 或 Promise
+});

+ 2 - 0
cypress/support/e2e.ts

@@ -3,6 +3,8 @@
 // Import commands.js using ES2015 syntax:
 import './commands';
 import './pageObjects/LoginPage';
+import './pageObjects/MainPage';
+import './pageObjects/WorklistPage';
 
 // Alternatively you can use CommonJS syntax:
 // require('./commands')

+ 53 - 0
cypress/support/pageObjects/MainPage.ts

@@ -0,0 +1,53 @@
+
+class MainPage {
+  visit() {
+    cy.visit('/');
+  }
+
+  clickPatientManagementButton() {
+    cy.get('button[data-testid="patient_management"]').click();
+  }
+
+  clickRegisterButton() {
+    cy.get('button[data-testid="register"]').click();
+  }
+
+  clickWorklistButton() {
+    cy.get('button[data-testid="worklist"]').click();
+  }
+
+  clickHistorylistButton() {
+    cy.get('button[data-testid="historylist"]').click();
+  }
+
+  clickArchivelistButton() {
+    cy.get('button[data-testid="archivelist"]').click();
+  }
+
+  clickBinButton() {
+    cy.get('button[data-testid="bin"]').click();
+  }
+
+  clickOutputlistButton() {
+    cy.get('button[data-testid="outputlist"]').click();
+  }
+
+  clickEmergencyButton() {
+    cy.get('button[data-testid="emergency"]').click();
+  }
+
+  clickExamButton() {
+    cy.get('button[data-testid="exam"]').click();
+  }
+
+  clickProcessButton() {
+    cy.get('button[data-testid="process"]').click();
+  }
+
+  clickPrintButton() {
+    cy.get('button[data-testid="print"]').click();
+  }
+}
+
+
+export default MainPage;

+ 9 - 0
cypress/support/pageObjects/WorklistPage.ts

@@ -0,0 +1,9 @@
+class WorklistPage {
+  findTableAndDoubleClickFirstRow() {
+    cy.get('table').within(() => {
+      cy.get('tbody tr[data-testid="row-0"]').scrollIntoView().should('be.visible').dblclick({ force: true });
+    });
+  }
+}
+
+export default WorklistPage;

+ 1 - 0
src/domain/mqttService.ts

@@ -73,6 +73,7 @@ const startListening = () => {
       handleMqttMessage(parsedMessage);
     } else if (topic === MQTT_GLOBAL_TOPIC) {
       const parsedMessage = JSON.parse(message.toString());
+      console.log(`读取到全局设备信息: ${message.toString()}`);
       if (parsedMessage.AllReady) {
         emitter.emit('AllReady_TRUE');
       } else {

+ 15 - 4
src/layouts/BusinessZone.tsx

@@ -16,6 +16,7 @@ interface BusinessZoneProps {
 }
 
 const BusinessZone: React.FC<BusinessZoneProps> = ({ onMenuClick }) => {
+  //eslint-disable-next-line @typescript-eslint/no-explicit-any
   const currentKey = useSelector((state: any) => state.BusinessFlow.currentKey);
   const items = [
     {
@@ -176,9 +177,16 @@ const BusinessZone: React.FC<BusinessZoneProps> = ({ onMenuClick }) => {
                 }}
               />
             ) : (
-              <div key={item.key} data-testid={item.key} className={item.key === currentKey ? 'border border-red-500' : ''}>
+              <div
+                key={item.key}
+                data-testid={item.key}
+                className={
+                  item.key === currentKey ? 'border border-red-500' : ''
+                }
+              >
                 <MeButton
                   icon={item.icon}
+                  data-testid={item.key}
                   onClick={
                     item.key === 'patient_management'
                       ? handlePatientManagementClick
@@ -187,15 +195,18 @@ const BusinessZone: React.FC<BusinessZoneProps> = ({ onMenuClick }) => {
                   username={item.label}
                 />
                 {item.key === 'patient_management' && floatingMenuVisible && (
-                  <Space direction="vertical" style={{ marginLeft: 20 }}
-                    >
+                  <Space direction="vertical" style={{ marginLeft: 20 }}>
                     {item.children?.map((child) => (
                       <MeButton
                         data-testid={child.key}
                         key={child.key}
                         onClick={() => onMenuClick?.(child.key)}
                         username={child.label}
-                        className={child.key === currentKey ? 'border border-red-500' : ''}
+                        className={
+                          child.key === currentKey
+                            ? 'border border-red-500'
+                            : ''
+                        }
                       />
                     ))}
                   </Space>

+ 33 - 18
src/pages/exam/DeviceArea.tsx

@@ -43,34 +43,49 @@ const DeviceArea = ({ className }: { className?: string }) => {
       />
       <Button
         style={btnStyle}
-        className={classValue}
+        data-testid="device-all-ready"
+        className={`${classValue} ${
+          exposureStatus === 'ready'
+            ? 'text-green-500'
+            : exposureStatus === 'not_ready'
+              ? ''
+              : ''
+        }`}
         icon={
           <CameraOutlined
-            className={
-              exposureStatus === 'ready'
-                ? 'text-green-500'
-                : exposureStatus === 'not_ready'
-                  ? ''
-                  : ''
-            }
+          // className={
+          //   exposureStatus === 'ready'
+          //     ? 'text-green-500'
+          //     : exposureStatus === 'not_ready'
+          //       ? ''
+          //       : ''
+          // }
           />
         }
         title={`曝光指示器: ${exposureStatus}`}
       />
       <Button
         style={btnStyle}
-        className={classValue}
+        className={`${classValue} ${
+          tabletStatus === 'exposing'
+            ? 'text-yellow-500'
+            : tabletStatus === 'ready'
+              ? 'text-green-500'
+              : tabletStatus === 'error'
+                ? 'text-red-500'
+                : ''
+        }`}
         icon={
           <TabletOutlined
-            className={
-              tabletStatus === 'exposing'
-                ? 'text-yellow-500'
-                : tabletStatus === 'ready'
-                  ? 'text-green-500'
-                  : tabletStatus === 'error'
-                    ? 'text-red-500'
-                    : ''
-            }
+          // className={
+          //   tabletStatus === 'exposing'
+          //     ? 'text-yellow-500'
+          //     : tabletStatus === 'ready'
+          //       ? 'text-green-500'
+          //       : tabletStatus === 'error'
+          //         ? 'text-red-500'
+          //         : ''
+          // }
           />
         }
         title={`平板指示器: ${tabletStatus}`}