diff --git a/clis/twitter/post.js b/clis/twitter/post.js index c79d19747..86bf24f04 100644 --- a/clis/twitter/post.js +++ b/clis/twitter/post.js @@ -235,7 +235,10 @@ async function submitTweet(page, text) { const boxes = Array.from(document.querySelectorAll('[data-testid="tweetTextarea_0"]')).filter(visible); const composerStillHasText = boxes.some((box) => normalize(box.innerText || box.textContent || '').includes(expectedText)); - const hasMedia = !!document.querySelector('[data-testid="attachments"], [data-testid="tweetPhoto"]') + // Drop the global tweetPhoto query: tweetPhoto exists for every + // timeline tweet's image and would pin hasMedia true past the + // success path. attachments + blob: URLs are composer-only. + const hasMedia = !!document.querySelector('[data-testid="attachments"]') || document.querySelectorAll('img[src^="blob:"], video[src^="blob:"]').length > 0; if (!composerStillHasText && !hasMedia) { return { ok: true, message: 'Tweet posted successfully.', ...statusUrl() }; diff --git a/clis/twitter/post.test.js b/clis/twitter/post.test.js index 13808c333..fbed1eb26 100644 --- a/clis/twitter/post.test.js +++ b/clis/twitter/post.test.js @@ -217,6 +217,23 @@ describe('twitter post command', () => { expect(submitScript).toContain('your post was sent'); }); + it('does not let global timeline tweetPhoto nodes keep the submit poll pending', async () => { + const command = getCommand(); + const page = makePage([ + { ok: true }, // focus composer + { ok: true }, // verify native insertText + { ok: true }, // click post + { ok: true, message: 'Tweet posted successfully.' }, + ]); + + await command.func(page, { text: 'global media should not block' }); + + const submitScript = page.evaluate.mock.calls[3][0]; + expect(submitScript).toContain("document.querySelector('[data-testid=\"attachments\"]')"); + expect(submitScript).not.toContain("[data-testid=\"attachments\"], [data-testid=\"tweetPhoto\"]"); + expect(submitScript).not.toContain("document.querySelectorAll('[data-testid=\"tweetPhoto\"]"); + }); + it('returns failed when image upload times out', async () => { const command = getCommand(); const page = makePage([