feat: support lark and feishu bot (#12712)

* feat: support lark and feishu

* chore: change integration to channel

* chore: rename from integration to channel

* fix: channel router

* feat: add topic list channel provider icon

* chore: update webhook url

* chore:  channel form refact

* chore: update i18n  keys to channel

* chore: update form item description

* style: hide required mark

* feat: add lark chat adapter

* chore: clean speaker tag  & add username api adapter

* chore: adjust topic channel icon

* chore: move developer mode to advanced setting

* chore: add lark icon

* fix: detail style

* fix: token check logic

* fix: encrpted risk

* fix: vercel function appId

* chore: remove webhook mode for discord

* chore: add doc link

* chore: add channel docs

* chore: remove unused import

* fix: create bot with wrong platform

* chore: update intergration to channel

* fix: udpate variable import

* fix: tsgo error

* chore: optimize webhook url trim

* chore: update copy text

* fix: telegram webhook not set

* chore: add persist logic

* docs: update feishu doc

* chore: update feishu and lark tenant

* chore: update docs

* chore: make verfication code required

* chore: update feishu docs

* chore: update verfication comment

* chore: update docs permission  list

* chore: verificationToken optional

* chore: update feishu and lark color

* chore: use test id
This commit is contained in:
Rdmclin2
2026-03-08 19:18:06 +08:00
committed by GitHub
parent 15a95156f3
commit 3f9c23e7b4
88 changed files with 3104 additions and 867 deletions

View File

@@ -11,7 +11,7 @@
import { Given, Then, When } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { CustomWorld } from '../../support/world';
import type { CustomWorld } from '../../support/world';
// ============================================
// Given Steps
@@ -158,25 +158,9 @@ When('用户点击另一个对话', async function (this: CustomWorld) {
}
// Fallback: try to find topic items in the sidebar
// Topics are displayed with star icons (lucide-star) in the left sidebar
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
// If not found by star, try finding by topic list structure
if (topicCount < 2) {
// Topics might be in a list container - look for items in sidebar with specific text
const topicItems = this.page.locator('[class*="nav-item"], [class*="NavItem"]');
topicCount = await topicItems.count();
console.log(` 📍 Found ${topicCount} nav items`);
if (topicCount >= 2) {
await topicItems.nth(1).click();
console.log(' ✅ 已点击另一个对话');
await this.page.waitForTimeout(500);
return;
}
}
const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
const topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topic items`);
// Click the second topic (first one is current/active)
if (topicCount >= 2) {
@@ -192,13 +176,11 @@ When('用户点击另一个对话', async function (this: CustomWorld) {
When('用户右键点击对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 右键点击对话...');
// Find topic items by their star icon - each saved topic has a star
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
const topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topic items`);
if (topicCount > 0) {
// Right-click the first saved topic
await sidebarTopics.first().click({ button: 'right' });
console.log(' ✅ 已右键点击对话');
} else {
@@ -211,10 +193,9 @@ When('用户右键点击对话', async function (this: CustomWorld) {
When('用户右键点击一个对话', async function (this: CustomWorld) {
console.log(' 📍 Step: 右键点击一个对话...');
// Find topic items by their star icon
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
let topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topics with star icons`);
const sidebarTopics = this.page.locator('[data-testid="topic-item"]');
const topicCount = await sidebarTopics.count();
console.log(` 📍 Found ${topicCount} topic items`);
// Store the topic text for later verification
if (topicCount > 0) {
@@ -238,7 +219,7 @@ When('用户选择重命名选项', async function (this: CustomWorld) {
// Instead of using right-click context menu, use the "..." dropdown menu
// which appears when hovering over a topic item
const topicItems = this.page.locator('svg.lucide-star').locator('..').locator('..');
const topicItems = this.page.locator('[data-testid="topic-item"]');
const topicCount = await topicItems.count();
console.log(` 📍 Found ${topicCount} topic items`);
@@ -253,7 +234,7 @@ When('用户选择重命名选项', async function (this: CustomWorld) {
// Important: we must find the icon WITHIN the hovered topic, not the global one
// The topic item has a specific structure with nav-item-actions
const moreButtonInTopic = firstTopic.locator('svg.lucide-ellipsis, svg.lucide-more-horizontal');
let moreButtonCount = await moreButtonInTopic.count();
const moreButtonCount = await moreButtonInTopic.count();
console.log(` 📍 Found ${moreButtonCount} more buttons inside topic`);
if (moreButtonCount > 0) {