fix(i18n): restore Composio labels on Connections Apps tab (#3569)

This commit is contained in:
Cyrus Gray
2026-06-10 14:44:13 +05:30
committed by GitHub
parent 04bec23405
commit 2595abac97
23 changed files with 79 additions and 75 deletions
+3 -3
View File
@@ -353,9 +353,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'مثبت',
'skills.explorer.install': 'تثبيت',
'skills.explorer.installing': 'جارٍ التثبيت…',
'skills.integrations': 'التطبيقات',
'skills.integrations': 'تكاملات Composio',
'skills.integrationsSubtitle':
'اتصالات OAuth السحابية — سجّل الدخول بحسابك وتُدار الرموز بأمان حتى يتمكن الوكلاء من القراءة والتصرف نيابةً عنك. لا حاجة لإدارة مفاتيح API.',
'اتصالات OAuth السحابية — سجّل الدخول بحسابك ويتولى Composio إدارة الرموز حتى يتمكن الوكلاء من القراءة والتصرف نيابةً عنك. لا حاجة لإدارة مفاتيح API.',
'skills.composio.noApiKeyTitle': 'لم يتم إعداد مفتاح Composio API',
'skills.composio.noApiKeyDescription':
'يستخدم الوضع المحلي مفتاح Composio API الخاص بك. افتح الإعدادات ← الخيارات المتقدمة ← Composio لإضافته قبل توصيل التكاملات هنا.',
@@ -4167,7 +4167,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'الويب',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'مدعوم من Composio',
'skills.composio.staleStatusTitle': 'تظهر الاتصالات حالة قديمة',
'skills.create.allowedTools': 'الأدوات المسموح بها',
'skills.create.allowedToolsHelp': 'تم عرضها في المادة الأمامية SKILL.md كـ',
+3 -3
View File
@@ -358,9 +358,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'ইনস্টল করা হয়েছে',
'skills.explorer.install': 'ইনস্টল করুন',
'skills.explorer.installing': 'ইনস্টল হচ্ছে…',
'skills.integrations': 'অ্যাপস',
'skills.integrations': 'Composio ইন্টিগ্রেশন',
'skills.integrationsSubtitle':
'ক্লাউড-ভিত্তিক OAuth সংযোগ — আপনার অ্যাকাউন্ট দিয়ে সাইন ইন করুন এবং টোকেন নিরাপদে পরিচালিত হয় যাতে এজেন্টরা আপনার পক্ষে পড়তে এবং কাজ করতে পারে। কোনো API কী পরিচালনা করতে হবে না।',
'ক্লাউড-ভিত্তিক OAuth সংযোগ — আপনার অ্যাকাউন্ট দিয়ে সাইন ইন করুন এবং Composio টোকেন পরিচালনা করে যাতে এজেন্টরা আপনার পক্ষে পড়তে এবং কাজ করতে পারে। কোনো API কী পরিচালনা করতে হবে না।',
'skills.composio.noApiKeyTitle': 'কোনো Composio API Key কনফিগার করা নেই',
'skills.composio.noApiKeyDescription':
'লোকাল মোডে আপনার নিজের Composio API key ব্যবহার হয়। এখানে ইন্টিগ্রেশন যুক্ত করার আগে Settings → Advanced → Composio খুলে একটি key যোগ করুন।',
@@ -4251,7 +4251,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'ওয়েব',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Composio দ্বারা চালিত',
'skills.composio.staleStatusTitle': 'সংযোগগুলি পুরানো অবস্থা দেখাচ্ছে',
'skills.create.allowedTools': 'অনুমোদিত টুল',
'skills.create.allowedToolsHelp': 'হিসাবে SKILL.md ফ্রন্টম্যাটারে রেন্ডার করা হয়েছে',
+3 -3
View File
@@ -369,9 +369,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Installiert',
'skills.explorer.install': 'Installieren',
'skills.explorer.installing': 'Wird installiert…',
'skills.integrations': 'Apps',
'skills.integrations': 'Composio-Integrationen',
'skills.integrationsSubtitle':
'Cloud-basierte OAuth-Verbindungen mit deinem Konto anmelden und Tokens werden sicher verwaltet, damit Agenten in deinem Namen lesen und handeln können. Keine API-Schlüssel notwendig.',
'Cloud-basierte OAuth-Verbindungen mit deinem Konto anmelden und Composio verwaltet die Tokens, damit Agenten in deinem Namen lesen und handeln können. Keine API-Schlüssel notwendig.',
'skills.composio.noApiKeyTitle': 'Kein Composio-API-Schlüssel konfiguriert',
'skills.composio.noApiKeyDescription':
'Im lokalen Modus wird dein eigener Composio-API-Schlüssel verwendet. Öffne Einstellungen → Erweitert → Composio, um einen Schlüssel hinzuzufügen, bevor du hier Integrationen verbindest.',
@@ -4364,7 +4364,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Unterstützt von Composio',
'skills.composio.staleStatusTitle': 'Verbindungen zeigen den veralteten Status an',
'skills.create.allowedTools': 'Erlaubte Werkzeuge',
'skills.create.allowedToolsHelp': 'Im SKILL.md-Frontmatter gerendert als',
+3 -3
View File
@@ -397,9 +397,9 @@ const en: TranslationMap = {
'skills.explorer.installed': 'Installed',
'skills.explorer.install': 'Install',
'skills.explorer.installing': 'Installing…',
'skills.integrations': 'Apps',
'skills.integrations': 'Composio Integrations',
'skills.integrationsSubtitle':
'Cloud-based OAuth connections — sign in with your account and tokens are brokered securely so agents can read and act on your behalf. No API keys to manage.',
'Cloud-based OAuth connections — sign in with your account and Composio brokers the tokens so agents can read and act on your behalf. No API keys to manage.',
'skills.composio.noApiKeyTitle': 'No Composio API Key Configured',
'skills.composio.noApiKeyDescription':
'Local mode uses your own Composio API key. Open Settings → Advanced → Composio to add one before connecting integrations here.',
@@ -4796,7 +4796,7 @@ const en: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Powered by Composio',
'skills.composio.staleStatusTitle': 'Connections are showing stale status',
'skills.create.allowedTools': 'Allowed tools',
'skills.create.allowedToolsHelp': 'Rendered into the SKILL.md frontmatter as',
+3 -3
View File
@@ -370,9 +370,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Instalada',
'skills.explorer.install': 'Instalar',
'skills.explorer.installing': 'Instalando…',
'skills.integrations': 'Aplicaciones',
'skills.integrations': 'Integraciones de Composio',
'skills.integrationsSubtitle':
'Conexiones OAuth en la nube: inicia sesión con tu cuenta y los tokens se gestionan de forma segura para que los agentes puedan leer y actuar en tu nombre. Sin claves de API que administrar.',
'Conexiones OAuth en la nube: inicia sesión con tu cuenta y Composio gestiona los tokens para que los agentes puedan leer y actuar en tu nombre. Sin claves de API que administrar.',
'skills.composio.noApiKeyTitle': 'No hay una API key de Composio configurada',
'skills.composio.noApiKeyDescription':
'El modo local usa tu propia API key de Composio. Abre Ajustes → Avanzado → Composio para añadir una antes de conectar integraciones aquí.',
@@ -4336,7 +4336,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Desarrollado por Composio',
'skills.composio.staleStatusTitle': 'Las conexiones muestran un estado obsoleto',
'skills.create.allowedTools': 'Herramientas permitidas',
'skills.create.allowedToolsHelp': 'Representado en el frontmatter de SKILL.md como',
+3 -3
View File
@@ -369,9 +369,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Installée',
'skills.explorer.install': 'Installer',
'skills.explorer.installing': 'Installation…',
'skills.integrations': 'Applications',
'skills.integrations': 'Intégrations Composio',
'skills.integrationsSubtitle':
'Connexions OAuth cloud — connectez-vous avec votre compte et les jetons sont gérés en toute sécurité pour que les agents puissent lire et agir en votre nom. Aucune clé API à gérer.',
'Connexions OAuth cloud — connectez-vous avec votre compte et Composio gère les jetons pour que les agents puissent lire et agir en votre nom. Aucune clé API à gérer.',
'skills.composio.noApiKeyTitle': 'Aucune clé API Composio configurée',
'skills.composio.noApiKeyDescription':
'Le mode local utilise votre propre clé API Composio. Ouvrez Paramètres → Avancé → Composio pour en ajouter une avant de connecter des intégrations ici.',
@@ -4354,7 +4354,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Propulsé par Composio',
'skills.composio.staleStatusTitle': 'Les connexions affichent un état obsolète',
'skills.create.allowedTools': 'Outils autorisés',
'skills.create.allowedToolsHelp': 'Rendu dans le frontmatter SKILL.md comme',
+3 -3
View File
@@ -357,9 +357,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'इंस्टॉल किया गया',
'skills.explorer.install': 'इंस्टॉल करें',
'skills.explorer.installing': 'इंस्टॉल हो रहा है…',
'skills.integrations': 'ऐप्स',
'skills.integrations': 'Composio इंटीग्रेशन',
'skills.integrationsSubtitle':
'क्लाउड-आधारित OAuth कनेक्शन — अपने अकाउंट से साइन इन करें और टोकन सुरक्षित रूप से प्रबंधित होते है ताकि एजेंट आपकी ओर से पढ़ और कार्य कर सकें। कोई API कुंजी प्रबंधित नहीं करनी।',
'क्लाउड-आधारित OAuth कनेक्शन — अपने अकाउंट से साइन इन करें और Composio टोकन ब्रोकर करता है ताकि एजेंट आपकी ओर से पढ़ और कार्य कर सकें। कोई API कुंजी प्रबंधित नहीं करनी।',
'skills.composio.noApiKeyTitle': 'कोई Composio API key कॉन्फ़िगर नहीं है',
'skills.composio.noApiKeyDescription':
'लोकल मोड आपकी अपनी Composio API key का उपयोग करता है। यहाँ integrations जोड़ने से पहले Settings → Advanced → Composio खोलकर key जोड़ें।',
@@ -4256,7 +4256,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'वेब',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Composio द्वारा संचालित',
'skills.composio.staleStatusTitle': 'कनेक्शन पुरानी स्थिति दिखा रहे हैं',
'skills.create.allowedTools': 'अनुमत टूल्स',
'skills.create.allowedToolsHelp': 'SKILL.md फ्रंटमैटर में प्रस्तुत किया गया',
+3 -3
View File
@@ -361,9 +361,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Terpasang',
'skills.explorer.install': 'Pasang',
'skills.explorer.installing': 'Memasang…',
'skills.integrations': 'Aplikasi',
'skills.integrations': 'Integrasi Composio',
'skills.integrationsSubtitle':
'Koneksi OAuth berbasis cloud — masuk dengan akun Anda dan token dikelola dengan aman agar agen dapat membaca dan bertindak atas nama Anda. Tidak perlu mengelola API key.',
'Koneksi OAuth berbasis cloud — masuk dengan akun Anda dan Composio mengelola token agar agen dapat membaca dan bertindak atas nama Anda. Tidak perlu mengelola API key.',
'skills.composio.noApiKeyTitle': 'Belum ada API key Composio yang dikonfigurasi',
'skills.composio.noApiKeyDescription':
'Mode lokal menggunakan API key Composio milik Anda sendiri. Buka Pengaturan → Lanjutan → Composio untuk menambahkannya sebelum menghubungkan integrasi di sini.',
@@ -4270,7 +4270,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Didukung oleh Composio',
'skills.composio.staleStatusTitle': 'Koneksi menunjukkan status basi',
'skills.create.allowedTools': 'Tool yang diizinkan',
'skills.create.allowedToolsHelp': 'Dirender ke frontmatter SKILL.md sebagai',
+3 -3
View File
@@ -365,9 +365,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Installata',
'skills.explorer.install': 'Installa',
'skills.explorer.installing': 'Installazione…',
'skills.integrations': 'App',
'skills.integrations': 'Integrazioni Composio',
'skills.integrationsSubtitle':
'Connessioni OAuth basate su cloud — accedi con il tuo account e i token sono gestiti in modo sicuro affinché gli agenti possano leggere e agire per tuo conto. Nessuna chiave API da gestire.',
'Connessioni OAuth basate su cloud — accedi con il tuo account e Composio gestisce i token affinché gli agenti possano leggere e agire per tuo conto. Nessuna chiave API da gestire.',
'skills.composio.noApiKeyTitle': 'Nessuna chiave API Composio configurata',
'skills.composio.noApiKeyDescription':
'La modalità locale usa la tua chiave API Composio. Apri Impostazioni → Avanzate → Composio per aggiungerne una prima di collegare le integrazioni qui.',
@@ -4329,7 +4329,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Offerto da Composio',
'skills.composio.staleStatusTitle': 'Le connessioni mostrano uno stato obsoleto',
'skills.create.allowedTools': 'Strumenti consentiti',
'skills.create.allowedToolsHelp': 'Resi nel frontmatter SKILL.md come',
+3 -3
View File
@@ -358,9 +358,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': '설치됨',
'skills.explorer.install': '설치',
'skills.explorer.installing': '설치 중…',
'skills.integrations': '',
'skills.integrations': 'Composio 통합',
'skills.integrationsSubtitle':
'클라우드 기반 OAuth 연결 — 계정으로 로그인하면 토큰이 안전하게 관리되어 에이전트가 사용자를 대신해 읽고 작동할 수 있습니다. API 키 관리가 필요 없습니다.',
'클라우드 기반 OAuth 연결 — 계정으로 로그인하면 Composio가 토큰을 관리하여 에이전트가 사용자를 대신해 읽고 작동할 수 있습니다. API 키 관리가 필요 없습니다.',
'skills.composio.noApiKeyTitle': '아니요 Composio API 키가 구성됨',
'skills.composio.noApiKeyDescription':
'로컬 모드에서는 자체 Composio API 키를 사용합니다. 설정 → 고급 → Composio에서 키를 추가한 후 여기서 통합을 연결하세요.',
@@ -4210,7 +4210,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': '웹',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Composio 제공',
'skills.composio.staleStatusTitle': '연결이 오래된 상태를 표시합니다.',
'skills.create.allowedTools': '허용된 도구',
'skills.create.allowedToolsHelp': 'SKILL.md 앞부분에 다음과 같이 렌더링됩니다.',
+3 -3
View File
@@ -363,9 +363,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Zainstalowano',
'skills.explorer.install': 'Zainstaluj',
'skills.explorer.installing': 'Instalowanie…',
'skills.integrations': 'Aplikacje',
'skills.integrations': 'Integracje Composio',
'skills.integrationsSubtitle':
'Chmurowe połączenia OAuth — zaloguj się swoim kontem, a tokeny są bezpiecznie zarządzane, dzięki czemu agenci mogą czytać i działać w Twoim imieniu. Bez kluczy API do utrzymywania.',
'Chmurowe połączenia OAuth — zaloguj się swoim kontem, a Composio pośredniczy w tokenach, dzięki czemu agenci mogą czytać i działać w Twoim imieniu. Bez kluczy API do utrzymywania.',
'skills.composio.noApiKeyTitle': 'Brak skonfigurowanego klucza API Composio',
'skills.composio.noApiKeyDescription':
'W trybie lokalnym używany jest Twój własny klucz API Composio. Otwórz Ustawienia → Zaawansowane → Composio, aby dodać klucz, zanim podłączysz tutaj integracje.',
@@ -4323,7 +4323,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Sieć',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Napędzane przez Composio',
'skills.composio.staleStatusTitle': 'Połączenia pokazują nieaktualny status',
'skills.create.allowedTools': 'Dozwolone narzędzia',
'skills.create.allowedToolsHelp': 'Renderowane do nagłówka frontmatter SKILL.md jako',
+3 -3
View File
@@ -369,9 +369,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Instalada',
'skills.explorer.install': 'Instalar',
'skills.explorer.installing': 'Instalando…',
'skills.integrations': 'Aplicativos',
'skills.integrations': 'Integrações do Composio',
'skills.integrationsSubtitle':
'Conexões OAuth baseadas em nuvem — faça login com sua conta e os tokens são gerenciados com segurança para que os agentes possam ler e agir em seu nome. Sem chaves de API para gerenciar.',
'Conexões OAuth baseadas em nuvem — faça login com sua conta e o Composio gerencia os tokens para que os agentes possam ler e agir em seu nome. Sem chaves de API para gerenciar.',
'skills.composio.noApiKeyTitle': 'Nenhuma chave de API do Composio configurada',
'skills.composio.noApiKeyDescription':
'O modo local usa sua própria chave de API do Composio. Abra Configurações → Avançado → Composio para adicionar uma antes de conectar integrações aqui.',
@@ -4331,7 +4331,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Web',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Desenvolvido por Composio',
'skills.composio.staleStatusTitle': 'As conexões estão mostrando status obsoleto',
'skills.create.allowedTools': 'Ferramentas permitidas',
'skills.create.allowedToolsHelp': 'Renderizado no frontmatter SKILL.md como',
+3 -3
View File
@@ -363,9 +363,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': 'Установлено',
'skills.explorer.install': 'Установить',
'skills.explorer.installing': 'Установка…',
'skills.integrations': 'Приложения',
'skills.integrations': 'Интеграции Composio',
'skills.integrationsSubtitle':
'Облачные OAuth-подключения — войдите в свой аккаунт, и токены управляются безопасно, чтобы агенты могли читать и действовать от вашего имени. Никаких API-ключей для управления.',
'Облачные OAuth-подключения — войдите в свой аккаунт, и Composio управляет токенами, чтобы агенты могли читать и действовать от вашего имени. Никаких API-ключей для управления.',
'skills.composio.noApiKeyTitle': 'Ключ API Composio не настроен',
'skills.composio.noApiKeyDescription':
'Локальный режим использует ваш собственный ключ API Composio. Откройте Настройки → Дополнительно → Composio, чтобы добавить ключ перед подключением интеграций здесь.',
@@ -4295,7 +4295,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': 'Интернет',
'skills.channelIcon.yuanbao': 'Yuanbao',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': 'Работает на Composio',
'skills.composio.staleStatusTitle': 'Соединения показывают устаревший статус',
'skills.create.allowedTools': 'Разрешённые инструменты',
'skills.create.allowedToolsHelp': 'Отображается в SKILL.md как',
+3 -3
View File
@@ -342,9 +342,9 @@ const messages: TranslationMap = {
'skills.explorer.installed': '已安装',
'skills.explorer.install': '安装',
'skills.explorer.installing': '安装中…',
'skills.integrations': '应用',
'skills.integrations': 'Composio 集成',
'skills.integrationsSubtitle':
'基于云端的 OAuth 连接——使用您的账户登录,令牌将被安全管理,让智能体能以您的名义读取数据并执行操作,无需管理 API 密钥。',
'基于云端的 OAuth 连接——使用您的账户登录,Composio 代管令牌,让智能体能以您的名义读取数据并执行操作,无需管理 API 密钥。',
'skills.composio.noApiKeyTitle': '尚未配置 Composio API 密钥',
'skills.composio.noApiKeyDescription':
'本地模式使用你自己的 Composio API 密钥。在此连接集成之前,请打开 设置 → 高级 → Composio 添加一个密钥。',
@@ -4043,7 +4043,7 @@ const messages: TranslationMap = {
'skills.channelIcon.telegram': 'Telegram',
'skills.channelIcon.web': '网络',
'skills.channelIcon.yuanbao': '元宝',
'skills.composio.poweredBy': 'OAuth',
'skills.composio.poweredBy': '由 Composio 提供支持',
'skills.composio.staleStatusTitle': '连接显示陈旧状态',
'skills.create.allowedTools': '允许的工具',
'skills.create.allowedToolsHelp': '渲染到 SKILL.md frontmatter 中为',
@@ -152,7 +152,7 @@ describe('Skills page — Channels grid', () => {
fireEvent.click(screen.getByRole('tab', { name: 'Apps' }));
// The Apps tab owns the Integrations category filter.
const integrationsHeading = screen.getByRole('heading', { name: 'Apps' });
const integrationsHeading = screen.getByRole('heading', { name: 'Composio Integrations' });
const integrationsCard = integrationsHeading.closest('.rounded-2xl');
expect(integrationsCard).not.toBeNull();
const filterTabs = within(integrationsCard as HTMLElement)
@@ -86,7 +86,7 @@ describe('Skills page — Composio catalog fallback', () => {
renderWithProviders(<Skills />, { initialEntries: ['/connections'] });
openAppsTab();
expect(screen.getByRole('heading', { name: 'Apps' })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: 'Composio Integrations' })).toBeInTheDocument();
expect(screen.getByText('Discord')).toBeInTheDocument();
expect(screen.getByText('Google Calendar')).toBeInTheDocument();
expect(screen.getByText('Google Drive')).toBeInTheDocument();
@@ -103,7 +103,7 @@ describe('Skills page — Composio catalog fallback', () => {
// missing Composio Zoom tile even though the Meeting bots card also
// renders a "Zoom" entry on the same page.
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
expect(within(integrationsSection as HTMLElement).getByText('Zoom')).toBeInTheDocument();
@@ -120,7 +120,7 @@ describe('Skills page — Composio catalog fallback', () => {
expect(screen.getByText('Backend unavailable')).toBeInTheDocument();
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
const gmailTile = within(integrationsSection as HTMLElement).getByRole('button', {
@@ -143,7 +143,7 @@ describe('Skills page — Composio catalog fallback', () => {
openAppsTab();
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
const gmailTile = within(integrationsSection as HTMLElement).getByRole('button', {
@@ -178,7 +178,7 @@ describe('Skills page — Composio catalog fallback', () => {
openAppsTab();
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
expect(within(integrationsSection as HTMLElement).getByText('2')).toBeInTheDocument();
@@ -198,7 +198,7 @@ describe('Skills page — Composio catalog fallback', () => {
openAppsTab();
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
// No Preview badges anywhere in the integrations grid. The
@@ -222,7 +222,7 @@ describe('Skills page — Composio catalog fallback', () => {
openAppsTab();
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
const zohoTile = within(integrationsSection as HTMLElement).getByRole('button', {
@@ -44,7 +44,7 @@ describe('Skills page — Gmail composio integration', () => {
fireEvent.click(screen.getByRole('tab', { name: 'Apps' }));
const integrationsSection = screen
.getByRole('heading', { name: 'Apps' })
.getByRole('heading', { name: 'Composio Integrations' })
.closest('.rounded-2xl');
expect(integrationsSection).not.toBeNull();
expect(within(integrationsSection as HTMLElement).getByText('Gmail')).toBeInTheDocument();
@@ -39,7 +39,7 @@ describe('Skills page — Notion composio integration', () => {
renderWithProviders(<Skills />, { initialEntries: ['/connections'] });
fireEvent.click(screen.getByRole('tab', { name: 'Apps' }));
expect(screen.getByRole('heading', { name: 'Apps' })).toBeInTheDocument();
expect(screen.getByRole('heading', { name: 'Composio Integrations' })).toBeInTheDocument();
const notionTile = screen.getByRole('button', { name: /Notion.*Connect/i });
expect(notionTile).toBeInTheDocument();
@@ -84,10 +84,10 @@ async function bootSkillsPage(page: Page, userId: string) {
await dismissWalkthroughIfPresent(page);
// Phase 2: "Composio" tab renamed to "Apps"
await page.getByRole('tab', { name: 'Apps' }).click();
// Phase 2: heading is now "Apps" (skills.integrations), "Composio Integrations" removed
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible({
timeout: 20_000,
});
// Heading reads "Composio Integrations" (skills.integrations); the tab is "Apps"
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible({ timeout: 20_000 });
}
async function openGmailManageModal(page: Page) {
@@ -186,11 +186,11 @@ test.describe('Composio triggers flow', () => {
await page.reload();
await waitForAppReady(page);
await dismissWalkthroughIfPresent(page);
// Phase 2: "Composio" tab renamed to "Apps"; heading is now "Apps"
// Tab is "Apps"; heading reads "Composio Integrations"
await page.getByRole('tab', { name: 'Apps' }).click();
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible({
timeout: 20_000,
});
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible({ timeout: 20_000 });
const dialog = await openGmailManageModal(page);
await expect(dialog.getByTestId('trigger-toggles')).toBeVisible();
@@ -77,7 +77,7 @@ async function bootSkillsPage(page: Page, userId: string) {
await dismissWalkthroughIfPresent(page);
// Phase 2: "Composio" tab renamed to "Apps"
await page.getByRole('tab', { name: 'Apps' }).click();
const heading = page.getByRole('heading', { name: 'Apps', exact: true });
const heading = page.getByRole('heading', { name: 'Composio Integrations', exact: true });
if (!(await heading.isVisible().catch(() => false))) {
const connectionsButton = page.getByRole('button', { name: 'Connections' });
if (await connectionsButton.isVisible().catch(() => false)) {
@@ -89,9 +89,9 @@ async function bootSkillsPage(page: Page, userId: string) {
await dismissWalkthroughIfPresent(page);
}
}
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible({
timeout: 20_000,
});
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible({ timeout: 20_000 });
}
async function reloadSkills(page: Page) {
@@ -100,7 +100,7 @@ async function reloadSkills(page: Page) {
async function ensureComposioSurface(page: Page) {
// Phase 2: /skills → /connections, "Composio" tab renamed to "Apps"
const heading = page.getByRole('heading', { name: 'Apps', exact: true });
const heading = page.getByRole('heading', { name: 'Composio Integrations', exact: true });
for (let attempt = 0; attempt < 3; attempt++) {
await page.evaluate(() => {
window.location.hash = '/connections';
@@ -74,9 +74,9 @@ async function bootSkills(page: Page, userId: string): Promise<void> {
await waitForAppReady(page);
await dismissWalkthroughIfPresent(page);
await page.getByRole('tab', { name: 'Apps' }).click();
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible({
timeout: 20_000,
});
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible({ timeout: 20_000 });
}
async function assertSessionAlive(page: Page): Promise<void> {
+7 -5
View File
@@ -70,10 +70,10 @@ async function bootSkillsPage(page: Page, userId: string) {
});
await waitForAppReady(page);
await dismissWalkthroughIfPresent(page);
// Phase 2: "Composio" tab renamed to "Apps"; heading is now "Apps" (skills.integrations)
// Tab is "Apps"; the h2 heading reads "Composio Integrations" (skills.integrations)
await page.getByRole('tab', { name: 'Apps' }).click();
// Wait for the Apps tab grid to be visible — the h2 heading text is now "Apps"
const heading = page.getByRole('heading', { name: 'Apps', exact: true });
// Wait for the Apps tab grid to be visible — the h2 heading text is "Composio Integrations"
const heading = page.getByRole('heading', { name: 'Composio Integrations', exact: true });
await expect(heading).toBeVisible({ timeout: 20_000 });
}
@@ -141,9 +141,11 @@ test.describe('Gmail Integration Flows', () => {
test('execute and disconnect routes do not blank the skills page', async ({ page }) => {
await callCoreRpc('openhuman.composio_execute', { tool: ACTION, arguments: {} });
// Phase 2: "Composio" tab renamed to "Apps"; heading is now "Apps" (skills.integrations)
// Tab is "Apps"; the h2 heading reads "Composio Integrations" (skills.integrations)
await page.getByRole('tab', { name: 'Apps' }).click();
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible();
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible();
await callCoreRpc('openhuman.composio_delete_connection', { connection_id: CONNECTION_ID });
const requests = await getRequestLog();
@@ -40,8 +40,10 @@ test.describe('Skills registry flow', () => {
await expect(page.getByRole('tab', { name: 'Messaging', exact: true })).toBeVisible();
await expect(page.getByRole('tab', { name: 'Tools', exact: true })).toBeVisible();
await page.getByRole('tab', { name: 'Apps', exact: true }).click();
// Phase 2: heading is now "Apps" (skills.integrations), "Composio Integrations" removed
await expect(page.getByRole('heading', { name: 'Apps', exact: true })).toBeVisible();
// Heading reads "Composio Integrations" (skills.integrations); the tab is "Apps"
await expect(
page.getByRole('heading', { name: 'Composio Integrations', exact: true })
).toBeVisible();
await expect(
page.getByText(/Gmail|Notion|Telegram|GitHub|Google Drive/, { exact: false }).first()
).toBeVisible();