From 6b39616be2a555ac3adefa3214bb673bf06ee498 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sat, 11 Jul 2026 10:52:26 -0300 Subject: [PATCH] Cover the composer alt-text round-trip with a browser test --- tests/Browser/AltTextTest.php | 87 +++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/Browser/AltTextTest.php diff --git a/tests/Browser/AltTextTest.php b/tests/Browser/AltTextTest.php new file mode 100644 index 00000000..f2ad3a30 --- /dev/null +++ b/tests/Browser/AltTextTest.php @@ -0,0 +1,87 @@ +script(<<<'JS' + (() => { + window.__autosaveDone = false; + const open = XMLHttpRequest.prototype.open; + const send = XMLHttpRequest.prototype.send; + XMLHttpRequest.prototype.open = function (method) { + this.__method = (method || '').toUpperCase(); + return open.apply(this, arguments); + }; + XMLHttpRequest.prototype.send = function () { + this.addEventListener('loadend', () => { + if (this.__method === 'PUT') { + window.__autosaveDone = true; + } + }); + return send.apply(this, arguments); + }; + })(); + JS); +} + +/** + * Poll on the browser side until the autosave PUT has completed, keeping the + * in-process server pumped while the debounce (1.5s) elapses and the request + * round-trips. + */ +function waitForAutosave(mixed $page): void +{ + $page->script(<<<'JS' + (async () => { + for (let attempt = 0; attempt < 100 && ! window.__autosaveDone; attempt++) { + await new Promise((resolve) => setTimeout(resolve, 100)); + } + })(); + JS); +} + +test('editing alt text on an attached image persists it to the post media', function () { + $user = User::factory()->create(); + $workspace = Workspace::factory()->create(['user_id' => $user->id]); + $workspace->members()->attach($user->id, ['role' => Role::Member->value]); + $user->update(['current_workspace_id' => $workspace->id]); + + $post = Post::factory()->create([ + 'workspace_id' => $workspace->id, + 'user_id' => $user->id, + 'content' => 'hello', + 'media' => [[ + 'id' => 'm1', + 'type' => 'image', + 'mime_type' => 'image/png', + 'path' => 'uploads/x.png', + 'url' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==', + ]], + ]); + + $this->actingAs($user); + + $page = visit(route('app.posts.edit', $post)); + + trackAutosave($page); + + $page->click('@alt-text-button') + ->type('@alt-text-input', 'a golden retriever on a beach') + ->click('@alt-text-save'); + + waitForAutosave($page); + + expect($post->fresh()->media[0]['meta']['alt_text']) + ->toBe('a golden retriever on a beach'); +});