seedLookupData(); $user = $this->user(['name' => 'Ticket Browser User']); $subject = 'Browser created helpdesk ticket '.uniqid(); $this->browse(function (Browser $browser) use ($user, $fixtures, $subject): void { $browser->loginAs($user) ->visitRoute('helpdesk.tickets.create') ->waitFor('@helpdesk-ticket-create') ->assertSee('Create ticket') ->type('@ticket-subject', $subject); $this->setHelpdeskEditor($browser, 'ticket-body-editor', '

This browser ticket proves the form saves correctly.

'); $this->setHelpdeskSelect($browser, 'board_id', $fixtures['board']->id); $this->setHelpdeskSelect($browser, 'priority_id', $fixtures['high']->id); $this->setHelpdeskSelect($browser, 'category_id', $fixtures['category']->id); $this->setHelpdeskSelect($browser, 'team_id', $fixtures['team']->id); $this->setHelpdeskSelect($browser, 'project_id', $fixtures['project']->id); $browser->pause(500) ->press('@ticket-create-submit') ->waitFor('@helpdesk-ticket-index', 10) ->assertSee($subject) ->assertSee('High') ->assertSee('Support'); }); } public function test_user_can_add_nested_response_in_browser(): void { $fixtures = $this->seedLookupData(); $user = $this->user(['name' => 'Response Browser User']); $ticket = $this->ticket([ 'owner' => $user, 'status_id' => $fixtures['open']->id, 'board_id' => $fixtures['board']->id, 'priority_id' => $fixtures['normal']->id, 'category_id' => $fixtures['category']->id, 'team_id' => $fixtures['team']->id, 'project_id' => $fixtures['project']->id, 'subject' => 'Browser response ticket', ]); $cannedResponse = CannedResponse::query()->create([ 'name' => 'Browser canned response', 'slug' => 'browser-canned-response', 'visibility' => 'agents', 'body' => '

Hello {{ requester.name }}

Inserted canned browser response for {{ ticket.reference }}

', 'is_active' => true, 'sort_order' => 1, ]); $this->browse(function (Browser $browser) use ($user, $ticket, $cannedResponse): void { $browser->loginAs($user) ->visitRoute('helpdesk.tickets.show', $ticket) ->waitFor('@helpdesk-ticket-show') ->assertSee('Browser response ticket') ->select('canned_response_id', (string) $cannedResponse->id) ->press('@insert-canned-response') ->waitForText('Hello Response Browser User', 10) ->assertSee('Inserted canned browser response') ->assertDontSee('

Hello') ->assertInputValue('subject', 'Browser canned response') ->assertInputValue('commentBody', '

Hello Response Browser User

Inserted canned browser response for '.$ticket->reference.'

') ->press('@post-comment') ->waitFor('@helpdesk-ticket-show', 10); $this->openHelpdeskConversation($browser); $browser->waitForText('Browser canned response', 10) ->assertSee('Browser canned response') ->assertDontSee('UNID') ->assertDontSee('GUID'); $comment = Comment::query() ->where('ticket_id', $ticket->id) ->whereNull('parent_id') ->where('body', 'like', '%Hello Response Browser User%') ->firstOrFail(); $this->openHelpdeskConversation($browser); $browser->press('@reply-to-comment-'.$comment->id) ->waitFor('@reply-body-'.$comment->id) ->type('@reply-body-'.$comment->id, 'Nested browser response') ->press('@post-reply-'.$comment->id) ->waitFor('@helpdesk-ticket-show', 10); $this->openHelpdeskConversation($browser); $browser->waitForText('RE: Browser canned response', 10) ->assertSee('RE: Browser canned response'); }); $this->assertDatabaseHas('helpdesk_comments', [ 'ticket_id' => $ticket->id, 'parent_id' => null, 'subject' => 'Browser canned response', 'body' => '

Hello Response Browser User

Inserted canned browser response for '.$ticket->reference.'

', ]); $parentId = Comment::query() ->where('ticket_id', $ticket->id) ->whereNull('parent_id') ->where('body', 'like', '%Inserted canned browser response%') ->value('id'); $this->assertDatabaseHas('helpdesk_comments', [ 'ticket_id' => $ticket->id, 'parent_id' => $parentId, 'subject' => 'RE: Browser canned response', 'body' => 'Nested browser response', ]); } private function openHelpdeskConversation(Browser $browser): void { $browser->script(<< { card.open = true; }); const update = window.updateCommentToggleButtons; if (typeof update === 'function') { update(); } JS); $browser->pause(150); } private function setHelpdeskEditor(Browser $browser, string $dusk, string $html): void { $encodedDusk = json_encode($dusk, JSON_THROW_ON_ERROR); $encodedHtml = json_encode($html, JSON_THROW_ON_ERROR); $browser->script(<</, '').replace(/<\/p>$/, ''); } else { editor.innerHTML = html; } editor.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true, inputType: 'insertText', data: editor.value || editor.textContent || ' ', })); editor.dispatchEvent(new Event('change', { bubbles: true, composed: true })); editor.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true, composed: true })); editor.dispatchEvent(new Event('blur', { bubbles: true, composed: true })); const model = root.getAttribute('wire:model') || root.getAttribute('wire:model.live') || root.getAttribute('wire:model.defer') || root.getAttribute('data-wire-model'); const componentRoot = root.closest('[wire\\\\:id]'); if (model && componentRoot && window.Livewire) { const component = window.Livewire.find(componentRoot.getAttribute('wire:id')); if (component) { component.set(model, html); } } JS); } private function setHelpdeskSelect(Browser $browser, string $model, int|string|null $value): void { $encodedModel = json_encode($model, JSON_THROW_ON_ERROR); $encodedValue = json_encode($value === null ? '' : (string) $value, JSON_THROW_ON_ERROR); $browser->script(<<