feat: réactions dans le tiroir Comments (+ suppression) et refonte du menu de sélection (v7.67.0)
FlowDeck CI / lint (push) Canceled after 0s
FlowDeck CI / test (push) Canceled after 0s
FlowDeck CI / docker (push) Canceled after 0s

Tiroir Comments
- Section « Reactions » au-dessus des fils : émoji, compte (si >1) et texte
  ancré lu dans le DOM (reactionList() / _anchorText(), offsets source hors
  pastilles) ; l'état vide ne s'affiche plus s'il reste des réactions.
- Suppression : ✕ sur la ligne du tiroir (mes réactions) ET croix ::after au
  survol de la pastille sur l'émoji que j'ai posé (aucun nœud ajouté → offsets
  intacts). Deux entrées → removeReaction() → POST toggle → loadReactions().

Menu de sélection (maquette ASCII)
- Ligne 4 = rangée scannée : 💬 Comment (libellé) à gauche, 🙂+ réaction à
  droite (.ft-row-split) ; la réaction sort de la ligne 3.
- Entête Skills avec ≡ à droite (::after), liste Skills scrollable.
- ✨ Ask AI retiré de la toolbar : doublon exact de « Edit with AI » du pied.
- Écart volontaire à la maquette : le barré (T) de la ligne 2 est conservé.

Fix racine (flake de gate)
- _is_public_host attrape OSError (le garde SSRF renvoie un booléen, il ne
  lève plus) : un socket.timeout DNS ne bascule plus fetch_og_metadata dans
  son except Exception → repli silencieux → AssertionError.
- fixture stub_dns sur TestOGParser (même motif que test_agent_web_tools) :
  zéro vrai DNS dans les tests OG.

Tests: pytest tests/ -q -n auto → 1390 passed / 0 failed (flake corrigé) ;
ruff check app tests → OK ; e2e v764 (réactions dans le tiroir + suppression
A/B), v762 (nouvelle ligne 4), v766, v7641, v763 → 6 passed sur :8081
(image flowdeck:v7.67.0 rebuild + redéployée).
This commit is contained in:
2026-10-08 14:25:48 -04:00
parent db6bf03a00
commit d58c321c07
16 changed files with 345 additions and 17 deletions
+6
View File
@@ -70,6 +70,12 @@ test('toolbar de sélection : structure, sous-menus, persistance', async ({ page
await expect(bar.locator('.ft-skill')).toHaveCount(4);
await expect(bar.locator('.ft-skill').first()).toHaveText('Improve writing');
await expect(bar.locator('.ft-foot')).toContainText('Edit with AI');
// refonte v7.67 : ligne 4 = Comment (libellé) à gauche, réaction à droite ;
// entête Skills avec ≡ ; plus de bouton ✨ Ask AI (doublon du pied)
await expect(bar.locator('.ft-comment')).toContainText('Comment');
await expect(bar.locator('.ft-row-split .ft-react')).toHaveCount(1);
await expect(bar.locator('.ft-skills-head')).toHaveText('Skills');
await expect(bar.locator('[data-tooltip^="Ask AI"]')).toHaveCount(0);
// géométrie : sous la sélection, entièrement dans le viewport
const barBox = await bar.boundingBox();
const selBox = await page.evaluate(() => {
+30
View File
@@ -168,4 +168,34 @@ test('réaction emoji + commentaires ancrés', async ({ page }) => {
await expect(page.locator('#_blocksCt .fd-anchor[data-cid]')).toHaveCount(1, { timeout: 10000 });
await expect(page.locator('#_blocksCt .fd-anchor[data-cid]')).toHaveText('reaction a un');
await expect(page.locator('#_blocksCt .fd-react-chip')).toHaveCount(1, { timeout: 10000 });
// ── 9. v7.67 : la réaction vit aussi dans le tiroir Comments ──
await page.locator('.topbar-btn[title="Comments"]').click();
const re = page.locator('.ct-reactions');
await expect(re).toBeVisible();
await expect(re.locator('.ct-re-emoji')).toHaveCount(1);
await expect(re.locator('.ct-re-text')).toHaveText('Prise de reaction a un texte');
await page.screenshot({ path: 'shots/v764-drawer-reactions.png' });
// ── 10. suppression A : ✕ de la section Réactions ──
await re.locator('.ct-reaction .ct-act').click();
await expect(page.locator('#_blocksCt .fd-react-chip')).toHaveCount(0);
await expect(re).toBeHidden();
// ── 11. suppression B : la croix survolée de la pastille ──
await page.locator('.topbar-btn[title="Comments"]').click(); // referme le tiroir
await selectBlock(page);
await page.locator('.format-toolbar .ft-react').click();
const picker2 = page.locator('.fd-icon-picker');
await expect(picker2).toBeVisible();
await picker2.locator('.fdip-emoji').first().click();
await expect(page.locator('#_blocksCt .fd-react-chip')).toHaveCount(1);
const emo = page.locator('#_blocksCt .fd-react-emo.is-mine');
await expect(emo).toHaveCount(1);
// la croix n'apparaît qu'au survol (::after)
await expect.poll(() => emo.evaluate((el) => getComputedStyle(el, '::after').display)).toBe('none');
await page.locator('#_blocksCt .fd-react-chip').hover();
await expect.poll(() => emo.evaluate((el) => getComputedStyle(el, '::after').display)).toBe('flex');
await emo.click();
await expect(page.locator('#_blocksCt .fd-react-chip')).toHaveCount(0);
});