Newer
Older
TelosDB / tests / e2e / specs / settings-folder-monitor.spec.js
/**
 * 設定パネル「モニター先フォルダ」の E2E テスト(計画 folder_monitor に基づく)。
 * - UI・保存・永続化・削除の検証
 * - 挙動: 監視フォルダにファイルを追加すると取り込まれ検索でヒットする
 *
 * 実行: npm run test:e2e
 * このスペックのみ: npx wdio run wdio.conf.js --spec tests/e2e/specs/settings-folder-monitor.spec.js
 */

import fs from 'fs';
import path from 'path';
import os from 'os';
import { waitForAppReady } from '../helpers/wait-for-app.js';

const openSettingsPanel = async () => {
  const navSettings = await $('button[data-panel="settings"]');
  await navSettings.click();
  const panel = await $('#panel-settings');
  await panel.waitForDisplayed({ timeout: 5000 });
  await expect(panel).not.toHaveElementClass('hidden');
};

describe('設定パネル モニター先フォルダ', () => {
  before(async function () {
    this.timeout(120000);
    await waitForAppReady(browser);
  });

  it('設定パネルにモニター先フォルダの追加ボタンとリストが表示される', async () => {
    await openSettingsPanel();
    const addBtn = await $('#settings-monitor-path-add');
    await expect(addBtn).toBeDisplayed();
    const list = await $('#settings-monitor-paths-list');
    await expect(list).toBeDisplayed();
  });

  it('追加ボタンで1行追加しパスを入力して保存すると「保存しました」が表示される', async () => {
    await openSettingsPanel();
    const addBtn = await $('#settings-monitor-path-add');
    await addBtn.click();
    const pathInput = await $('.setting-monitor-path');
    await pathInput.waitForDisplayed({ timeout: 3000 });
    await pathInput.setValue('C:\\Test\\Watch');
    await (await $('#settings-save-btn')).click();
    const feedback = await $('#settings-feedback');
    await expect(feedback).toHaveText('保存しました');
  });

  it('パスを1件保存後、いったん検索パネルに切り替えてから設定を再表示すると入力したパスが表示される', async () => {
    await openSettingsPanel();
    const addBtn = await $('#settings-monitor-path-add');
    await addBtn.click();
    const pathInput = await $('.setting-monitor-path');
    await pathInput.waitForDisplayed({ timeout: 3000 });
    await pathInput.setValue('D:\\Documents\\Notes');
    await (await $('#settings-save-btn')).click();
    await browser.pause(500);
    await (await $('button[data-panel="search"]')).click();
    await browser.pause(300);
    await openSettingsPanel();
    // 非同期で設定を読み込むため、パス入力が表示されるまで待つ
    await browser.waitUntil(
      async () => (await $$('.setting-monitor-path')).length > 0,
      { timeout: 5000 }
    );
    const pathInputs = await $$('.setting-monitor-path');
    const values = await Promise.all(Array.from(pathInputs).map((el) => el.getValue()));
    expect(values).toContain('D:\\Documents\\Notes');
  });

  it('削除ボタンで行を削除して保存し、再表示すると行が消えている', async () => {
    await openSettingsPanel();
    const addBtn = await $('#settings-monitor-path-add');
    await addBtn.click();
    const pathInput = await $('.setting-monitor-path');
    await pathInput.waitForDisplayed({ timeout: 3000 });
    await pathInput.setValue('E:\\ToRemove');
    await (await $('#settings-save-btn')).click();
    await browser.pause(500);
    const removeBtn = await $('.setting-monitor-path-remove');
    await removeBtn.click();
    await (await $('#settings-save-btn')).click();
    await browser.pause(500);
    await (await $('button[data-panel="search"]')).click();
    await browser.pause(300);
    await openSettingsPanel();
    // 設定再読み込み後、リストが更新されるまで待つ(空になるか他行のみになる)
    await browser.pause(800);
    const pathInputs = await $$('.setting-monitor-path');
    const values = await Promise.all(Array.from(pathInputs).map((el) => el.getValue()));
    expect(values.some((v) => v === 'E:\\ToRemove')).toBe(false);
  });

  it('監視フォルダに .txt を追加すると取り込まれ検索でヒットする(挙動確認)', async function () {
    this.timeout(25000);
    const watchDir = fs.mkdtempSync(path.join(os.tmpdir(), 'telosdb-e2e-watch-'));
    const uniquePhrase = `E2E_FOLDER_MONITOR_${Date.now()}_取り込み`;
    const testFilePath = path.join(watchDir, 'e2e-watched-file.txt');
    try {
      await openSettingsPanel();
      const addBtn = await $('#settings-monitor-path-add');
      await addBtn.click();
      const pathInput = await $('.setting-monitor-path');
      await pathInput.waitForDisplayed({ timeout: 3000 });
      await pathInput.setValue(watchDir);
      await (await $('#settings-save-btn')).click();
      const feedback = await $('#settings-feedback');
      await expect(feedback).toHaveText('保存しました');
      await browser.pause(500);

      fs.writeFileSync(testFilePath, uniquePhrase, 'utf8');

      // デバウンス 2 秒 + インデックス反映の余裕
      await browser.pause(5500);

      await (await $('button[data-panel="search"]')).click();
      await browser.pause(500);
      const searchInput = await $('#query');
      const searchBtn = await $('.search-btn');
      await searchInput.setValue(uniquePhrase);
      await searchBtn.click();
      await browser.pause(3000);

      const resultCards = await $$('.result-card');
      expect(resultCards.length).toBeGreaterThanOrEqual(1);
      const firstCardText = await resultCards[0].getText();
      expect(firstCardText).toContain(uniquePhrase);
    } finally {
      try {
        fs.unlinkSync(testFilePath);
        fs.rmdirSync(watchDir);
      } catch (_) {}
    }
  });
});