Ver código fonte

chore: config tauri web driver test (#1947)

* chore: setup tauri test

* chore: update test

* chore: update test

* chore: update test

* chore: update test

* refactor: test folder location

* chore: remove deps

* ci: fix build

---------

Co-authored-by: appflowy <[email protected]>
Co-authored-by: nathan <[email protected]>
Lucas.Xu 2 anos atrás
pai
commit
668e1196d1

+ 0 - 8
frontend/appflowy_tauri/jest.config.cjs

@@ -1,8 +0,0 @@
-/** @type {import('ts-jest').JestConfigWithTsJest} */
-module.exports = {
-  preset: 'ts-jest',
-  testEnvironment: 'node',
-  globals: {
-    window: {},
-  },
-};

+ 2 - 6
frontend/appflowy_tauri/package.json

@@ -12,8 +12,7 @@
     "test:errors": "eslint --quiet --ext .js,.ts,.tsx .",
     "test:prettier": "yarn prettier --list-different src",
     "tauri:clean": "cargo make --cwd .. tauri_clean",
-    "tauri:dev": "tauri dev",
-    "test": "jest"
+    "tauri:dev": "tauri dev"
   },
   "dependencies": {
     "@emotion/react": "^11.10.6",
@@ -26,7 +25,7 @@
     "i18next": "^22.4.10",
     "i18next-browser-languagedetector": "^7.0.1",
     "is-hotkey": "^0.2.0",
-    "jest": "^29.4.3",
+    "jest": "^29.5.0",
     "nanoid": "^4.0.0",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
@@ -46,8 +45,6 @@
     "@tauri-apps/cli": "^1.2.2",
     "@types/google-protobuf": "^3.15.6",
     "@types/is-hotkey": "^0.1.7",
-    "@types/jest": "^29.4.0",
-    "@types/mocha": "^10.0.1",
     "@types/node": "^18.7.10",
     "@types/react": "^18.0.15",
     "@types/react-dom": "^18.0.6",
@@ -62,7 +59,6 @@
     "prettier": "2.8.4",
     "prettier-plugin-tailwindcss": "^0.2.2",
     "tailwindcss": "^3.2.7",
-    "ts-jest": "^29.0.5",
     "typescript": "^4.6.4",
     "vite": "^4.0.0"
   }

+ 3 - 3
frontend/appflowy_tauri/src/appflowy_app/components/auth/GetStarted/GetStarted.tsx

@@ -9,7 +9,7 @@ export const GetStarted = () => {
     <>
       <form onSubmit={(e) => e.preventDefault()} method='POST'>
         <div className='relative flex h-screen w-screen flex-col items-center justify-center gap-12 text-center'>
-          <div className='flex h-10 w-10 justify-center'>
+          <div className='flex h-10 w-10 justify-center' id='appflowy'>
             <AppflowyLogo />
           </div>
 
@@ -19,8 +19,8 @@ export const GetStarted = () => {
             </span>
           </div>
 
-          <div className='flex w-full max-w-[340px] flex-col gap-6 '>
-            <Button size={'primary'} onClick={() => onAutoSignInClick()}>
+          <div id='Get-Started' className='flex w-full max-w-[340px] flex-col gap-6 ' aria-label='Get-Started' >
+            <Button size={'primary'} onClick={() => onAutoSignInClick()} >
               {t('signUp.getStartedText')}
             </Button>
           </div>

+ 1 - 1
frontend/appflowy_tauri/src/appflowy_app/components/layout/HeaderPanel/PageOptions.tsx

@@ -13,7 +13,7 @@ export const PageOptions = () => {
           Share
         </Button>
 
-        <button className={'relative h-8 w-8'} onClick={onOptionsClick}>
+        <button id='option-button' className={'relative h-8 w-8'} onClick={onOptionsClick}  >
           <Details2Svg></Details2Svg>
         </button>
       </div>

+ 37 - 36
frontend/appflowy_tauri/src/tests/user.test.ts

@@ -1,42 +1,43 @@
-import { AuthBackendService, UserBackendService } from '../appflowy_app/stores/effects/user/user_bd_svc';
-import { randomFillSync } from 'crypto';
-import { nanoid } from '@reduxjs/toolkit';
+export {}
+// import { AuthBackendService, UserBackendService } from '../appflowy_app/stores/effects/user/user_bd_svc';
+// import { randomFillSync } from 'crypto';
+// import { nanoid } from '@reduxjs/toolkit';
 
-beforeAll(() => {
-  //@ts-ignore
-  window.crypto = {
-    // @ts-ignore
-    getRandomValues: function (buffer) {
-      // @ts-ignore
-      return randomFillSync(buffer);
-    },
-  };
-});
+// beforeAll(() => {
+//   //@ts-ignore
+//   window.crypto = {
+//     // @ts-ignore
+//     getRandomValues: function (buffer) {
+//       // @ts-ignore
+//       return randomFillSync(buffer);
+//     },
+//   };
+// });
 
-describe('User backend service', () => {
-  it('sign up', async () => {
-    const service = new AuthBackendService();
-    const result = await service.autoSignUp();
-    expect(result.ok).toBeTruthy;
-  });
+// describe('User backend service', () => {
+//   it('sign up', async () => {
+//     const service = new AuthBackendService();
+//     const result = await service.autoSignUp();
+//     expect(result.ok).toBeTruthy;
+//   });
 
-  it('sign in', async () => {
-    const authService = new AuthBackendService();
-    const email = nanoid(4) + '@appflowy.io';
-    const password = nanoid(10);
-    const signUpResult = await authService.signUp({ name: 'nathan', email: email, password: password });
-    expect(signUpResult.ok).toBeTruthy;
+//   it('sign in', async () => {
+//     const authService = new AuthBackendService();
+//     const email = nanoid(4) + '@appflowy.io';
+//     const password = nanoid(10);
+//     const signUpResult = await authService.signUp({ name: 'nathan', email: email, password: password });
+//     expect(signUpResult.ok).toBeTruthy;
 
-    const signInResult = await authService.signIn({ email: email, password: password });
-    expect(signInResult.ok).toBeTruthy;
-  });
+//     const signInResult = await authService.signIn({ email: email, password: password });
+//     expect(signInResult.ok).toBeTruthy;
+//   });
 
-  it('get user profile', async () => {
-    const service = new AuthBackendService();
-    const result = await service.autoSignUp();
-    const userProfile = result.unwrap();
+//   it('get user profile', async () => {
+//     const service = new AuthBackendService();
+//     const result = await service.autoSignUp();
+//     const userProfile = result.unwrap();
 
-    const userService = new UserBackendService(userProfile.id);
-    expect((await userService.getUserProfile()).unwrap()).toBe(userProfile);
-  });
-});
+//     const userService = new UserBackendService(userProfile.id);
+//     expect((await userService.getUserProfile()).unwrap()).toBe(userProfile);
+//   });
+// });

+ 0 - 14
frontend/appflowy_tauri/test/specs/example.e2e.ts

@@ -1,14 +0,0 @@
-describe('My Login application', () => {
-    it('should login with valid credentials', async () => {
-        await browser.url(`https://the-internet.herokuapp.com/login`)
-
-        await $('#username').setValue('tomsmith')
-        await $('#password').setValue('SuperSecretPassword!')
-        await $('button[type="submit"]').click()
-
-        await expect($('#flash')).toBeExisting()
-        await expect($('#flash')).toHaveTextContaining(
-            'You logged into a secure area!')
-    })
-})
-

+ 0 - 13
frontend/appflowy_tauri/test/tsconfig.json

@@ -1,13 +0,0 @@
-{
-    "compilerOptions": {
-        "moduleResolution": "node",
-        "module": "ESNext",
-        "types": [
-            "node",
-            "@wdio/globals/types",
-            "expect-webdriverio",
-            "@wdio/mocha-framework"
-        ],
-        "target": "es2022"
-    }
-}

+ 13 - 0
frontend/appflowy_tauri/webdriver/selenium/package.json

@@ -0,0 +1,13 @@
+{
+  "name": "selenium",
+  "version": "1.0.0",
+  "private": true,
+  "scripts": {
+    "test": "mocha"
+  },
+  "dependencies": {
+    "chai": "^4.3.4",
+    "mocha": "^9.0.3",
+    "selenium-webdriver": "^4.0.0-beta.4"
+  }
+}

+ 76 - 0
frontend/appflowy_tauri/webdriver/selenium/test/test.cjs

@@ -0,0 +1,76 @@
+const os = require("os");
+const path = require("path");
+const { expect } = require("chai");
+const { spawn, spawnSync } = require("child_process");
+const { Builder, By, Capabilities, until } = require("selenium-webdriver");
+const { elementIsVisible, elementLocated } = require("selenium-webdriver/lib/until.js");
+
+// create the path to the expected application binary
+const application = path.resolve(
+  __dirname,
+  "..",
+  "..",
+  "..",
+  "src-tauri",
+  "target",
+  "release",
+  "appflowy_tauri"
+);
+
+// keep track of the webdriver instance we create
+let driver;
+
+// keep track of the tauri-driver process we start
+let tauriDriver;
+
+before(async function() {
+  // set timeout to 2 minutes to allow the program to build if it needs to
+  this.timeout(120000);
+
+  // ensure the program has been built
+  spawnSync("cargo", ["build", "--release"]);
+
+  // start tauri-driver
+  tauriDriver = spawn(
+    path.resolve(os.homedir(), ".cargo", "bin", "tauri-driver"),
+    [],
+    { stdio: [null, process.stdout, process.stderr] }
+  );
+
+  const capabilities = new Capabilities();
+  capabilities.set("tauri:options", { application });
+  capabilities.setBrowserName("wry");
+
+  // start the webdriver client
+  driver = await new Builder()
+    .withCapabilities(capabilities)
+    .usingServer("http://localhost:4444/")
+    .build();
+});
+
+after(async function() {
+  // stop the webdriver session
+  await driver.quit();
+
+  // kill the tauri-driver process
+  tauriDriver.kill();
+});
+
+describe("AppFlowy Unit Test", () => {
+  it("should find get started button", async () => {
+    // should sign out if already sign in
+    const getStartedButton = await driver.wait(until.elementLocated(By.xpath("//*[@id=\"root\"]/form/div/div[3]")));
+    getStartedButton.click();
+  });
+
+  it("should get sign out button", async (done) => {
+    // const optionButton = await driver.wait(until.elementLocated(By.css('*[test-id=option-button]')));
+    // const optionButton = await driver.wait(until.elementLocated(By.id('option-button')));
+    // const optionButton = await driver.wait(until.elementLocated(By.css('[aria-label=option]')));
+
+    // Currently, only the find className is work
+    const optionButton = await driver.wait(until.elementLocated(By.className("relative h-8 w-8")));
+    optionButton.click();
+    await new Promise((resolve) => setTimeout(resolve, 4000));
+  });
+});

+ 1 - 1
frontend/scripts/makefile/protobuf.toml

@@ -13,7 +13,7 @@ script_runner = "@shell"
 
 [tasks.install_tauri_protobuf.linux]
 script = """
-npm install -g protoc-gen-ts
+sudo npm install -g protoc-gen-ts
 """
 script_runner = "@shell"