# Search Results

## Redirecting Redirecting to full-page components
Redirecting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/redirecting

## Redirecting to full-page components

Because Livewire uses Laravel's built-in redirection feature, you can use all of the redirection methods available to you in a typical Laravel application.

For example, if you are using a Livewire component as a full-page component for a route like so:

```php
Route::livewire('/posts', 'pages::show-posts');
```

You can redirect to it simply by using the route path:

```php
public function save()
{
    // ...

    $this->redirect('/posts');
}
```

---

## Responses Redirects Redirecting With Flashed Session Data Redirecting With Input
Responses | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/responses.md

#### Redirecting With Input

You may use the `withInput` method provided by the `RedirectResponse` instance to flash the current request's input data to the session before redirecting the user to a new location. This is typically done if the user has encountered a validation error. Once the input has been flashed to the session, you may easily [retrieve it](/docs/{{version}}/requests#retrieving-old-input) during the next request to repopulate the form:

```php
return back()->withInput();
```

---

## Testing Calling actions
Testing | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing

## Calling actions

Use the `call()` method to trigger component actions in your tests:

```php
use App\Models\Post;

it('can create a post', function () {
    expect(Post::count())->toBe(0);

    Livewire::test('post.create')
        ->set('title', 'My new post')
        ->set('content', 'Post content here')
        ->call('save');

    expect(Post::count())->toBe(1);
});
```

> [!tip] Pest expectations
> The examples above use Pest's `expect()` syntax for assertions. For a complete list of available expectations, see the [Pest expectations documentation](https://pestphp.com/docs/expectations).

You can pass parameters to actions:

```php
Livewire::test('post.show')
    ->call('deletePost', $postId);
```

### Testing validation

Assert that validation errors have been thrown using `assertHasErrors()`:

```php
it('title field is required', function () {
    Livewire::test('post.create')
        ->set('title', '')
        ->call('save')
        ->assertHasErrors('title');
});
```

Test specific validation rules:

```php
it('title must be at least 3 characters', function () {
    Livewire::test('post.create')
        ->set('title', 'ab')
        ->call('save')
        ->assertHasErrors(['title' => ['min:3']]);
});
```

### Testing authorization

Ensure authorization checks work correctly using `assertUnauthorized()` and `assertForbidden()`:

```php
use App\Models\User;
use App\Models\Post;

it('cannot update another users post', function () {
    $user = User::factory()->create();
    $stranger = User::factory()->create();
    $post = Post::factory()->for($stranger)->create();

    Livewire::actingAs($user)
        ->test('post.edit', ['post' => $post])
        ->set('title', 'Hacked!')
        ->call('save')
        ->assertForbidden();
});
```

### Testing redirects

Assert that an action performed a redirect:

```php
it('redirects to posts index after creating', function () {
    Livewire::test('post.create')
        ->set('title', 'New post')
        ->set('content', 'Content here')
        ->call('save')
        ->assertRedirect('/posts');
});
```

You can also assert redirects to named routes or page components:

```php
->assertRedirect(route('posts.index'));
->assertRedirectToRoute('posts.index');
```

### Testing events

Assert that events were dispatched from your component:

```php
it('dispatches event when post is created', function () {
    Livewire::test('post.create')
        ->set('title', 'New post')
        ->call('save')
        ->assertDispatched('post-created');
});
```

Test event communication between components:

```php
it('updates post count when event is dispatched', function () {
    $badge = Livewire::test('post-count-badge')
        ->assertSee('0');

    Livewire::test('post.create')
        ->set('title', 'New post')
        ->call('save')
        ->assertDispatched('post-created');

    $badge->dispatch('post-created')
        ->assertSee('1');
});
```

Assert events were dispatched with specific parameters:

```php
it('dispatches notification when deleting post', function () {
    Livewire::test('post.show')
        ->call('delete', postId: 3)
        ->assertDispatched('notify', message: 'Post deleted');
});
```

For complex assertions, use a closure:

```php
it('dispatches event with correct data', function () {
    Livewire::test('post.show')
        ->call('delete', postId: 3)
        ->assertDispatched('notify', function ($event, $params) {
            return ($params['message'] ?? '') === 'Post deleted';
        });
});
```

### Testing JS evaluation

Assert that a component evaluated JavaScript via `$this->js()`:

```php
it('shows an alert after saving', function () {
    Livewire::test('post.create')
        ->set('title', 'New post')
        ->call('save')
        ->assertJs("alert('Post saved!')");
});
```

You can also assert that no JS was evaluated:

```php
->assertNoJs();
```

---

## Requests Input Old Input Flashing Input Then Redirecting
Requests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/requests.md

#### Flashing Input Then Redirecting

Since you often will want to flash input to the session and then redirect to the previous page, you may easily chain input flashing onto a redirect using the `withInput` method:

```php
return redirect('/form')->withInput();

return redirect()->route('user.create')->withInput();

return redirect('/form')->withInput(
    $request->except('password')
);
```

---

## Http Tests Validation Assertions assertInvalid
Http Tests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/http-tests.md

#### assertInvalid

Assert that the response has validation errors for the given keys. This method may be used for asserting against responses where the validation errors are returned as a JSON structure or where the validation errors have been flashed to the session:

```php
$response->assertInvalid(['name', 'email']);
```

You may also assert that a given key has a particular validation error message. When doing so, you may provide the entire message or only a small portion of the message:

```php
$response->assertInvalid([
    'name' => 'The name field is required.',
    'email' => 'valid email address',
]);
```

---

## Testing See also
Testing | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing

## See also

- **[Actions](/docs/4.x/actions)** — Test component actions and interactions
- **[Forms](/docs/4.x/forms)** — Test form submissions and validation
- **[Events](/docs/4.x/events)** — Test event dispatching and listening
- **[Components](/docs/4.x/components)** — Create testable component structure

---

## Validation Form objects
Validation | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/validation

## Form objects

As more properties and validation rules are added to a Livewire component, it can begin to feel too crowded. To alleviate this pain and also provide a helpful abstraction for code reuse, you can use Livewire's *Form Objects* to store your properties and validation rules.

Below is the same `CreatePost` example, but now the properties and rules have been extracted to a dedicated form object named `PostForm`:

```php
<?php

namespace App\Livewire\Forms;

use Livewire\Attributes\Validate;
use Livewire\Form;

class PostForm extends Form
{
    #[Validate('required|min:3')]
	public $title = '';

    #[Validate('required|min:3')]
    public $content = '';
}
```

The `PostForm` above can now be defined as a property on the `CreatePost` component:

```php
<?php

namespace App\Livewire;

use App\Livewire\Forms\PostForm;
use Livewire\Component;
use App\Models\Post;

class CreatePost extends Component
{
    public PostForm $form;

    public function save()
    {
		Post::create(
    		$this->form->all()
    	);

		return redirect()->to('/posts');
    }

    // ...
}
```

As you can see, instead of listing out each property individually, we can retrieve all the property values using the `->all()` method on the form object.

Also, when referencing the property names in the template, you must prepend `form.` to each instance:

```blade
<form wire:submit="save">
	<input type="text" wire:model="form.title">
    <div>@error('form.title') {{ $message }} @enderror</div>

	<textarea wire:model="form.content"></textarea>
    <div>@error('form.content') {{ $message }} @enderror</div>

	<button type="submit">Save</button>
</form>
```

When using form objects, `#[Validate]` attribute validation will be run every time a property is updated. However, if you disable this behavior by specifying `onUpdate: false` on the attribute, you can manually run a form object's validation using `$this->form->validate()`:

```php
public function save()
{
    Post::create(
        $this->form->validate()
    );

    return redirect()->to('/posts');
}
```

Form objects are a useful abstraction for most larger datasets and a variety of additional features that make them even more powerful. For more information, check out the comprehensive [form object documentation](/docs/4.x/forms#extracting-a-form-object).

---

## Requests Input Old Input Flashing Input to the Session
Requests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/requests.md

#### Flashing Input to the Session

The `flash` method on the `Illuminate\Http\Request` class will flash the current input to the [session](/docs/{{version}}/session) so that it is available during the user's next request to the application:

```php
$request->flash();
```

You may also use the `flashOnly` and `flashExcept` methods to flash a subset of the request data to the session. These methods are useful for keeping sensitive information such as passwords out of the session:

```php
$request->flashOnly(['username', 'email']);

$request->flashExcept('password');
```

---

## Understanding Nesting Performance implications
Understanding Nesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/understanding-nesting

## Performance implications

Livewire's independent component architecture can have both positive and negative implications for your application.

An advantage of this architecture is it allows you to isolate expensive portions of your application. For example, you can quarantine a slow database query to its own independent component, and its performance overhead won't impact the rest of the page.

However, the biggest drawback of this approach is that because components are entirely separate, inter-component communication/dependencies becomes more difficult.

For example, if you had a property passed down from the above parent `Posts` component to the nested `ShowPost` component, it wouldn't be "reactive". Because each component is independent, if a request to the parent component changed the value of the property being passed into `ShowPost`, it wouldn't update inside `ShowPost`.

Livewire has overcome a number of these hurdles and provides dedicated APIs for these scenarios like: [Reactive properties](/docs/4.x/nesting#reactive-props), [Modelable components](/docs/4.x/nesting#binding-to-child-data-using-wiremodel), and [the `$parent` object](/docs/4.x/nesting#directly-accessing-the-parent-from-the-child).

Armed with this knowledge of how nested Livewire components operate, you will be able to make more informed decisions about when and how to nest components within your application.

---

## Test Impact Analysis
Test Impact Analysis | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/test-impact-analysis.md

---
title: Test Impact Analysis (TIA)
description: Test Impact Analysis is a great way to drastically reduce the time it takes to run your test suite by re-running only the tests affected by your latest changes.
---

# Test Impact Analysis (TIA)

Test Impact Analysis is a great way to drastically reduce the time it takes to run your test suite by re-running only the tests affected by your latest changes. The first time you run with `--tia`, Pest records a graph of which tests depend on which files. Every run after that, Pest looks at what you changed, runs only the tests that touched those files, and replays cached results for everything else.

A typical Laravel suite that takes 15 seconds replays in under a second. Edits to a single Blade template re-run a handful of feature tests. Comment-only edits, formatter passes, and README touches re-run nothing at all.

To get started, just add the `--tia` flag to any Pest invocation:

```bash
./vendor/bin/pest --parallel --tia
```

The first run is the **baseline** — Pest enables a coverage driver (PCOV or Xdebug) and records the dependency graph as your tests execute. Expect a small overhead on this run only.

Every subsequent run is a **replay**. Pest compares your working tree against the baseline and re-runs only the tests affected by your changes:

```
Tests:    774 passed (2658 assertions, 7 affected, 767 replayed)
Duration: 0.74s
```

`affected` is the set of tests Pest actually executed. `replayed` is the set whose results were served from cache.

## How Pest Decides What To Run

For each file you've changed, Pest looks for tests that depend on it:

- **PHP source files** — your `app/` classes, controllers, models, helpers — are tracked through the coverage driver. A change to `app/Models/User.php` re-runs only the tests that touched `User`.
- **Migrations** are intersected with the tables each test queried during the baseline. A column rename in `create_users_table.php` re-runs only the tests that queried the `users` table.
- **Inertia pages** under `resources/js/Pages` re-run only the tests that server-side-rendered them.
- **Shared JS components** under `resources/js/Components`, `Layouts`, and friends re-run only the tests whose pages import them — Pest walks Vite's module graph to figure this out.
- **Blade templates** re-run only the tests that rendered them, including renders triggered by browser tests.
- **Anything else** — config files, route files, `.env`, files outside the recorded graph — falls through to a broader pattern. Editing `config/app.php` re-runs every test, because Pest can't statically prove which tests depend on it.

## Cosmetic Edits Don't Run Anything

Pest normalises file content before comparing, so cosmetic changes don't trigger any tests. PHP files have whitespace, line comments, and docblocks stripped before hashing. Blade strips `{{-- … --}}` comments. JS, TS, Vue, and Svelte files have line and block comments removed too.

The result: a comment-only edit, a Prettier reformat, a Pint pass, or a README tweak produces an identical hash, and the file never enters the changed set. Zero tests run.

## Modes

Pest supports a few flags alongside `--tia`:

| Flag | Behaviour |
|---|---|
| `--tia` | Replay if a baseline graph exists, otherwise record. |
| `--tia --fresh` | Discard any existing graph and re-record from scratch. Use this after large refactors or when the graph feels stale. |
| `--tia --refetch` | Force a CI baseline fetch even within the 24-hour cooldown after a previous failed fetch.

## Sharing The Baseline From CI

Recording the baseline locally takes minutes on large suites. Instead, you can have CI record it once per merge to `main`, and every developer downloads the result.

When Pest detects no local graph (or the local graph is out of date), it uses GitHub's CLI to download the latest successful run of a `tia-baseline.yml` workflow's `pest-tia-baseline` artifact. Pest validates the fetched graph against your project state — if it matches, it's adopted. Otherwise it's discarded and a local rebuild proceeds.

Here's a starter workflow you can drop into `.github/workflows/tia-baseline.yml`:

```yaml
name: TIA Baseline
on:
  push: { branches: [main] }
  schedule: [{ cron: '0 3 * * *' }]
  workflow_dispatch:
jobs:
  baseline:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: shivammathur/setup-php@v2
        with: { php-version: '8.5', coverage: xdebug }
      - run: composer install --no-interaction --prefer-dist
      - run: ./vendor/bin/pest --parallel --tia --coverage
      - name: Stage baseline for upload
        shell: bash
        run: |
          mkdir -p .pest-tia-baseline
          cp -R "$HOME/.pest/tia"/*/. .pest-tia-baseline/
      - uses: actions/upload-artifact@v4
        with:
          name: pest-tia-baseline
          path: .pest-tia-baseline/
          retention-days: 30
```

After CI runs, every developer who runs `pest --tia` for the first time on the repo will download this baseline and start replaying immediately, paying no record cost.

## Storage

Pest stores its state at `~/.pest/tia/<project-key>/`, where the project key is derived from your normalised git remote URL — so `git@github.com:foo/bar.git` and `https://github.com/foo/bar` produce the same key. A non-git project falls back to a hash of the project's absolute path.

Sharing state per remote URL means multiple worktrees of the same repository share one cache, while unrelated projects on the same machine stay isolated.

## Custom Watch Patterns

If your project has a directory layout that doesn't match the framework defaults, you can register custom watch patterns in `tests/Pest.php`:

```php
pest()->tia()->watch([
    'config/billing/**/*.php' => ['tests/Feature/Billing'],

    //
]);
```

Each glob maps to a list of test directories; whenever a matching file changes, every test under those directories is invalidated. Use this when you have specific test directories that genuinely depend on a file Pest can't see otherwise.

---

Now that you've learned how to use Test Impact Analysis to speed up your test suite, let's discuss how to integrate Pest with your continuous integration workflow: [Continuous Integration](/docs/continuous-integration)

---

## Validation Testing validation
Validation | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/validation

## Testing validation

Livewire provides useful testing utilities for validation scenarios, such as the `assertHasErrors()` method.

Below is a basic test case that ensures validation errors are thrown if no input is set for the `title` property:

```php
<?php

namespace Tests\Feature\Livewire;

use App\Livewire\CreatePost;
use Livewire\Livewire;
use Tests\TestCase;

class CreatePostTest extends TestCase
{
    public function test_cant_create_post_without_title()
    {
        Livewire::test(CreatePost::class)
            ->set('content', 'Sample content...')
            ->call('save')
            ->assertHasErrors('title');
    }
}
```

In addition to testing the presence of errors, `assertHasErrors` allows you to also narrow down the assertion to specific rules by passing the rules to assert against as the second argument to the method:

```php
public function test_cant_create_post_with_title_shorter_than_3_characters()
{
    Livewire::test(CreatePost::class)
        ->set('title', 'Sa')
        ->set('content', 'Sample content...')
        ->call('save')
        ->assertHasErrors(['title' => ['min:3']]);
}
```

You can also assert the presence of validation errors for multiple properties at the same time:

```php
public function test_cant_create_post_without_title_and_content()
{
    Livewire::test(CreatePost::class)
        ->call('save')
        ->assertHasErrors(['title', 'content']);
}
```

For more information on other testing utilities provided by Livewire, check out the [testing documentation](/docs/4.x/testing).

---

## Forms See also
Forms | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/forms

## See also

- **[Validation](/docs/4.x/validation)** — Validate form inputs with real-time feedback
- **[wire:model](/docs/4.x/wire-model)** — Bind form inputs to component properties
- **[File Uploads](/docs/4.x/uploads)** — Handle file uploads in forms
- **[Actions](/docs/4.x/actions)** — Process form submissions with actions
- **[Loading States](/docs/4.x/loading-states)** — Show loading indicators during form submission

---

## Browser Testing assertButtonDisabled
Browser Testing | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md

### assertButtonDisabled

The `assertButtonDisabled` method asserts that the given button is disabled:

```php
$page->assertButtonDisabled('Submit');
```

## URL Assertions

---

## Lifecycle Hooks Using hooks inside a form object
Lifecycle Hooks | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/lifecycle-hooks

## Using hooks inside a form object

Form objects in Livewire support property update hooks. These hooks work similarly to [component update hooks](#update), letting you perform actions when properties in the form object change.

Below is an example of a component using a `PostForm` form object:

```php
<?php // resources/views/components/post/⚡create.blade.php

use Livewire\Component;

new class extends Component {
    public PostForm $form;

    // ...
};
```

Here's the `PostForm` form object containing all the available hooks:

```php
namespace App\Livewire\Forms;

use Livewire\Attributes\Validate;
use Livewire\Form;

class PostForm extends Form
{
    public $title = '';

    public $tags = [];

    public function updating($property, $value)
    {
        // ...
    }

    public function updated($property, $value)
    {
        // ...
    }

    public function updatingTitle($value)
    {
        // ...
    }

    public function updatedTitle($value)
    {
        // ...
    }

    public function updatingTags($value, $key)
    {
        // ...
    }

    public function updatedTags($value, $key)
    {
        // ...
    }

    // ...
}
```

---

## Filtering Tests `only()`
Filtering Tests | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/filtering-tests.md

### `only()`

During development, you may want to focus on running specific tests while excluding all others. Pest provides two ways to do this: running only tests in a specific file, or running only a specific test within a file.

#### Running Only Tests in a File

When working on a specific feature, you can mark all tests in a file to run exclusively by calling the `pest()->only()` function at the top of your test file:

```php
<?php

pest()->only();

test('first test', function () {
    // This will run
});

test('second test', function () {
    // This will also run
});
```

All tests in files with `pest()->only()` will run, while tests in other files will be skipped.

#### Running a Single Test

To run only a specific test within a file, chain the `->only()` method to the test:

```php
test('sum', function () {
  $result = sum(1, 2);

  expect($result)->toBe(3);
})->only();

test('another test', function () {
  // This will be skipped
});
```

---

As your codebase grows, manually running your tests with filtering can become tedious. That's where skipping tests comes in. Skipping tests is a useful feature that allows developers to exclude specific tests from the test suite temporarily without deleting them entirely: [Skipping Tests →](/docs/skipping-tests)

---

## Validation Form Request Validation Creating Form Requests Customizing the Redirect Location
Validation | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/validation.md

#### Customizing the Redirect Location

When form request validation fails, a redirect response will be generated to send the user back to their previous location. However, you are free to customize this behavior. To do so, define a `$redirect` property on your form request:

```php
/**
 * The URI that users should be redirected to if validation fails.
 *
 * @var string
 */
protected $redirect = '/dashboard';
```

Or, if you would like to redirect users to a named route, you may define a `$redirectRoute` property instead:

```php
/**
 * The route that users should be redirected to if validation fails.
 *
 * @var string
 */
protected $redirectRoute = 'dashboard';
```

---

## Testing All available testing methods
Testing | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing

## All available testing methods

Below is a comprehensive reference of every Livewire testing method available to you:

### Setup methods

| Method                                                  | Description                                                                                |
|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `Livewire::test('post.create')`                      | Test the `post.create` component |
| `Livewire::test(UpdatePost::class, ['post' => $post])`                      | Test the `UpdatePost` component with parameters passed to `mount()` |
| `Livewire::actingAs($user)`                      | Set the authenticated user for the test |
| `Livewire::withQueryParams(['search' => '...'])`                      | Set URL query parameters (ex. `?search=...`) |
| `Livewire::withCookie('name', 'value')`                      | Set a cookie for the test |
| `Livewire::withCookies(['color' => 'blue', 'name' => 'Taylor'])`                      | Set multiple cookies |
| `Livewire::withHeaders(['X-Header' => 'value'])`                      | Set custom headers |
| `Livewire::withoutLazyLoading()`                      | Disable lazy loading for all components in this test |

### Interacting with components

| Method                                                  | Description                                                                                |
|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `set('title', '...')`                      | Set the `title` property to the provided value |
| `set(['title' => '...', 'content' => '...'])`                      | Set multiple properties using an array |
| `toggle('sortAsc')`                      | Toggle a boolean property between `true` and `false`  |
| `call('save')`                      | Call the `save` action/method |
| `call('remove', $postId)`                      | Call a method with parameters |
| `refresh()`                      | Trigger a component re-render |
| `dispatch('post-created')`                      | Dispatch an event from the component  |
| `dispatch('post-created', postId: $post->id)`                      | Dispatch an event with parameters |

### Assertions

| Method                                                | Description                                                                                |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `assertSet('title', '...')`                           | Assert that a property equals the provided value                                                                                |
| `assertNotSet('title', '...')`                        | Assert that a property does not equal the provided value                                                                                |
| `assertCount('posts', 3)`                             | Assert that a property contains 3 items                                                                                |
| `assertSee('...')`                             | Assert that the rendered HTML contains the provided text                                                                                |
| `assertDontSee('...')`                         | Assert that the rendered HTML does not contain the provided text                                                                                |
| `assertSeeHtml('<div>...</div>')`                     | Assert that raw HTML is present in the rendered output |
| `assertDontSeeHtml('<div>...</div>')`                 | Assert that raw HTML is not present in the rendered output                                                                                |
| `assertSeeInOrder(['first', 'second'])`                    | Assert that strings appear in order in the rendered output                                                                                |
| `assertDispatched('post-created')`                    | Assert that an event was dispatched                                                                                |
| `assertNotDispatched('post-created')`                 | Assert that an event was not dispatched                                                                                |
| `assertHasErrors('title')`                            | Assert that validation failed for a property                                                                                |
| `assertHasErrors(['title' => ['required', 'min:6']])`   | Assert that specific validation rules failed                                                                                |
| `assertHasNoErrors('title')`                          | Assert that there are no validation errors for a property                                                                                |
| `assertRedirect()`                                    | Assert that a redirect was triggered                                                                                |
| `assertRedirect('/posts')`                            | Assert a redirect to a specific URL                                                                                |
| `assertRedirectToRoute('posts.index')`       | Assert a redirect to a named route                                                                                |
| `assertNoRedirect()`                                  | Assert that no redirect was triggered                                                                                |
| `assertViewHas('posts')`                              | Assert that data was passed to the view                                                                                |
| `assertViewHas('postCount', 3)`                       | Assert that view data has a specific value                                                                                |
| `assertViewHas('posts', function ($posts) { ... })`   | Assert view data passes custom validation                                                                         |
| `assertViewIs('livewire.show-posts')`                 | Assert that a specific view was rendered                                                                                |
| `assertJs("alert('...')")`                            | Assert that a JS expression was evaluated                                                                                |
| `assertNoJs()`                                        | Assert that no JS was evaluated                                                                                |
| `assertFileDownloaded()`                              | Assert that a file download was triggered                                                                                |
| `assertFileDownloaded($filename)`                     | Assert that a specific file was downloaded                                                                                |
| `assertUnauthorized()`                                | Assert that an authorization exception was thrown (401)                                                                                |
| `assertForbidden()`                                   | Assert that access was forbidden (403)                                                                                |
| `assertStatus(500)`                                   | Assert that a specific status code was returned                                                                                |

_[Truncated]_


Output:
Wall time: 3.4930 seconds
Output:
[{"type":"text","text":"# Search Results\n\n## Redirecting Redirecting to full-page components\nRedirecting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/redirecting\n\n## Redirecting to full-page components\n\nBecause Livewire uses Laravel's built-in redirection feature, you can use all of the redirection methods available to you in a typical Laravel application.\n\nFor example, if you are using a Livewire component as a full-page component for a route like so:\n\n```php\nRoute::livewire('/posts', 'pages::show-posts');\n```\n\nYou can redirect to it simply by using the route path:\n\n```php\npublic function save()\n{\n    // ...\n\n    $this->redirect('/posts');\n}\n```\n\n---\n\n## Responses Redirects Redirecting With Flashed Session Data Redirecting With Input\nResponses | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/responses.md\n\n\n#### Redirecting With Input\n\nYou may use the `withInput` method provided by the `RedirectResponse` instance to flash the current request's input data to the session before redirecting the user to a new location. This is typically done if the user has encountered a validation error. Once the input has been flashed to the session, you may easily [retrieve it](/docs/{{version}}/requests#retrieving-old-input) during the next request to repopulate the form:\n\n```php\nreturn back()->withInput();\n```\n\n---\n\n## Testing Calling actions\nTesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing\n\n## Calling actions\n\nUse the `call()` method to trigger component actions in your tests:\n\n```php\nuse App\\Models\\Post;\n\nit('can create a post', function () {\n    expect(Post::count())->toBe(0);\n\n    Livewire::test('post.create')\n        ->set('title', 'My new post')\n        ->set('content', 'Post content here')\n        ->call('save');\n\n    expect(Post::count())->toBe(1);\n});\n```\n\n> [!tip] Pest expectations\n> The examples above use Pest's `expect()` syntax for assertions. For a complete list of available expectations, see the [Pest expectations documentation](https://pestphp.com/docs/expectations).\n\nYou can pass parameters to actions:\n\n```php\nLivewire::test('post.show')\n    ->call('deletePost', $postId);\n```\n\n### Testing validation\n\nAssert that validation errors have been thrown using `assertHasErrors()`:\n\n```php\nit('title field is required', function () {\n    Livewire::test('post.create')\n        ->set('title', '')\n        ->call('save')\n        ->assertHasErrors('title');\n});\n```\n\nTest specific validation rules:\n\n```php\nit('title must be at least 3 characters', function () {\n    Livewire::test('post.create')\n        ->set('title', 'ab')\n        ->call('save')\n        ->assertHasErrors(['title' => ['min:3']]);\n});\n```\n\n### Testing authorization\n\nEnsure authorization checks work correctly using `assertUnauthorized()` and `assertForbidden()`:\n\n```php\nuse App\\Models\\User;\nuse App\\Models\\Post;\n\nit('cannot update another users post', function () {\n    $user = User::factory()->create();\n    $stranger = User::factory()->create();\n    $post = Post::factory()->for($stranger)->create();\n\n    Livewire::actingAs($user)\n        ->test('post.edit', ['post' => $post])\n        ->set('title', 'Hacked!')\n        ->call('save')\n        ->assertForbidden();\n});\n```\n\n### Testing redirects\n\nAssert that an action performed a redirect:\n\n```php\nit('redirects to posts index after creating', function () {\n    Livewire::test('post.create')\n        ->set('title', 'New post')\n        ->set('content', 'Content here')\n        ->call('save')\n        ->assertRedirect('/posts');\n});\n```\n\nYou can also assert redirects to named routes or page components:\n\n```php\n->assertRedirect(route('posts.index'));\n->assertRedirectToRoute('posts.index');\n```\n\n### Testing events\n\nAssert that events were dispatched from your component:\n\n```php\nit('dispatches event when post is created', function () {\n    Livewire::test('post.create')\n        ->set('title', 'New post')\n        ->call('save')\n        ->assertDispatched('post-created');\n});\n```\n\nTest event communication between components:\n\n```php\nit('updates post count when event is dispatched', function () {\n    $badge = Livewire::test('post-count-badge')\n        ->assertSee('0');\n\n    Livewire::test('post.create')\n        ->set('title', 'New post')\n        ->call('save')\n        ->assertDispatched('post-created');\n\n    $badge->dispatch('post-created')\n        ->assertSee('1');\n});\n```\n\nAssert events were dispatched with specific parameters:\n\n```php\nit('dispatches notification when deleting post', function () {\n    Livewire::test('post.show')\n        ->call('delete', postId: 3)\n        ->assertDispatched('notify', message: 'Post deleted');\n});\n```\n\nFor complex assertions, use a closure:\n\n```php\nit('dispatches event with correct data', function () {\n    Livewire::test('post.show')\n        ->call('delete', postId: 3)\n        ->assertDispatched('notify', function ($event, $params) {\n            return ($params['message'] ?? '') === 'Post deleted';\n        });\n});\n```\n\n### Testing JS evaluation\n\nAssert that a component evaluated JavaScript via `$this->js()`:\n\n```php\nit('shows an alert after saving', function () {\n    Livewire::test('post.create')\n        ->set('title', 'New post')\n        ->call('save')\n        ->assertJs(\"alert('Post saved!')\");\n});\n```\n\nYou can also assert that no JS was evaluated:\n\n```php\n->assertNoJs();\n```\n\n---\n\n## Requests Input Old Input Flashing Input Then Redirecting\nRequests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/requests.md\n\n\n#### Flashing Input Then Redirecting\n\nSince you often will want to flash input to the session and then redirect to the previous page, you may easily chain input flashing onto a redirect using the `withInput` method:\n\n```php\nreturn redirect('/form')->withInput();\n\nreturn redirect()->route('user.create')->withInput();\n\nreturn redirect('/form')->withInput(\n    $request->except('password')\n);\n```\n\n---\n\n## Http Tests Validation Assertions assertInvalid\nHttp Tests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/http-tests.md\n\n\n#### assertInvalid\n\nAssert that the response has validation errors for the given keys. This method may be used for asserting against responses where the validation errors are returned as a JSON structure or where the validation errors have been flashed to the session:\n\n```php\n$response->assertInvalid(['name', 'email']);\n```\n\nYou may also assert that a given key has a particular validation error message. When doing so, you may provide the entire message or only a small portion of the message:\n\n```php\n$response->assertInvalid([\n    'name' => 'The name field is required.',\n    'email' => 'valid email address',\n]);\n```\n\n---\n\n## Testing See also\nTesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing\n\n## See also\n\n- **[Actions](/docs/4.x/actions)** — Test component actions and interactions\n- **[Forms](/docs/4.x/forms)** — Test form submissions and validation\n- **[Events](/docs/4.x/events)** — Test event dispatching and listening\n- **[Components](/docs/4.x/components)** — Create testable component structure\n\n---\n\n## Validation Form objects\nValidation | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/validation\n\n## Form objects\n\nAs more properties and validation rules are added to a Livewire component, it can begin to feel too crowded. To alleviate this pain and also provide a helpful abstraction for code reuse, you can use Livewire's *Form Objects* to store your properties and validation rules.\n\nBelow is the same `CreatePost` example, but now the properties and rules have been extracted to a dedicated form object named `PostForm`:\n\n```php\n<?php\n\nnamespace App\\Livewire\\Forms;\n\nuse Livewire\\Attributes\\Validate;\nuse Livewire\\Form;\n\nclass PostForm extends Form\n{\n    #[Validate('required|min:3')]\n\tpublic $title = '';\n\n    #[Validate('required|min:3')]\n    public $content = '';\n}\n```\n\nThe `PostForm` above can now be defined as a property on the `CreatePost` component:\n\n```php\n<?php\n\nnamespace App\\Livewire;\n\nuse App\\Livewire\\Forms\\PostForm;\nuse Livewire\\Component;\nuse App\\Models\\Post;\n\nclass CreatePost extends Component\n{\n    public PostForm $form;\n\n    public function save()\n    {\n\t\tPost::create(\n    \t\t$this->form->all()\n    \t);\n\n\t\treturn redirect()->to('/posts');\n    }\n\n    // ...\n}\n```\n\nAs you can see, instead of listing out each property individually, we can retrieve all the property values using the `->all()` method on the form object.\n\nAlso, when referencing the property names in the template, you must prepend `form.` to each instance:\n\n```blade\n<form wire:submit=\"save\">\n\t<input type=\"text\" wire:model=\"form.title\">\n    <div>@error('form.title') {{ $message }} @enderror</div>\n\n\t<textarea wire:model=\"form.content\"></textarea>\n    <div>@error('form.content') {{ $message }} @enderror</div>\n\n\t<button type=\"submit\">Save</button>\n</form>\n```\n\nWhen using form objects, `#[Validate]` attribute validation will be run every time a property is updated. However, if you disable this behavior by specifying `onUpdate: false` on the attribute, you can manually run a form object's validation using `$this->form->validate()`:\n\n```php\npublic function save()\n{\n    Post::create(\n        $this->form->validate()\n    );\n\n    return redirect()->to('/posts');\n}\n```\n\nForm objects are a useful abstraction for most larger datasets and a variety of additional features that make them even more powerful. For more information, check out the comprehensive [form object documentation](/docs/4.x/forms#extracting-a-form-object).\n\n---\n\n## Requests Input Old Input Flashing Input to the Session\nRequests | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/requests.md\n\n\n#### Flashing Input to the Session\n\nThe `flash` method on the `Illuminate\\Http\\Request` class will flash the current input to the [session](/docs/{{version}}/session) so that it is available during the user's next request to the application:\n\n```php\n$request->flash();\n```\n\nYou may also use the `flashOnly` and `flashExcept` methods to flash a subset of the request data to the session. These methods are useful for keeping sensitive information such as passwords out of the session:\n\n```php\n$request->flashOnly(['username', 'email']);\n\n$request->flashExcept('password');\n```\n\n---\n\n## Understanding Nesting Performance implications\nUnderstanding Nesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/understanding-nesting\n\n## Performance implications\n\nLivewire's independent component architecture can have both positive and negative implications for your application.\n\nAn advantage of this architecture is it allows you to isolate expensive portions of your application. For example, you can quarantine a slow database query to its own independent component, and its performance overhead won't impact the rest of the page.\n\nHowever, the biggest drawback of this approach is that because components are entirely separate, inter-component communication/dependencies becomes more difficult.\n\nFor example, if you had a property passed down from the above parent `Posts` component to the nested `ShowPost` component, it wouldn't be \"reactive\". Because each component is independent, if a request to the parent component changed the value of the property being passed into `ShowPost`, it wouldn't update inside `ShowPost`.\n\nLivewire has overcome a number of these hurdles and provides dedicated APIs for these scenarios like: [Reactive properties](/docs/4.x/nesting#reactive-props), [Modelable components](/docs/4.x/nesting#binding-to-child-data-using-wiremodel), and [the `$parent` object](/docs/4.x/nesting#directly-accessing-the-parent-from-the-child).\n\nArmed with this knowledge of how nested Livewire components operate, you will be able to make more informed decisions about when and how to nest components within your application.\n\n---\n\n## Test Impact Analysis\nTest Impact Analysis | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/test-impact-analysis.md\n\n---\ntitle: Test Impact Analysis (TIA)\ndescription: Test Impact Analysis is a great way to drastically reduce the time it takes to run your test suite by re-running only the tests affected by your latest changes.\n---\n\n# Test Impact Analysis (TIA)\n\nTest Impact Analysis is a great way to drastically reduce the time it takes to run your test suite by re-running only the tests affected by your latest changes. The first time you run with `--tia`, Pest records a graph of which tests depend on which files. Every run after that, Pest looks at what you changed, runs only the tests that touched those files, and replays cached results for everything else.\n\nA typical Laravel suite that takes 15 seconds replays in under a second. Edits to a single Blade template re-run a handful of feature tests. Comment-only edits, formatter passes, and README touches re-run nothing at all.\n\nTo get started, just add the `--tia` flag to any Pest invocation:\n\n```bash\n./vendor/bin/pest --parallel --tia\n```\n\nThe first run is the **baseline** — Pest enables a coverage driver (PCOV or Xdebug) and records the dependency graph as your tests execute. Expect a small overhead on this run only.\n\nEvery subsequent run is a **replay**. Pest compares your working tree against the baseline and re-runs only the tests affected by your changes:\n\n```\nTests:    774 passed (2658 assertions, 7 affected, 767 replayed)\nDuration: 0.74s\n```\n\n`affected` is the set of tests Pest actually executed. `replayed` is the set whose results were served from cache.\n\n## How Pest Decides What To Run\n\nFor each file you've changed, Pest looks for tests that depend on it:\n\n- **PHP source files** — your `app/` classes, controllers, models, helpers — are tracked through the coverage driver. A change to `app/Models/User.php` re-runs only the tests that touched `User`.\n- **Migrations** are intersected with the tables each test queried during the baseline. A column rename in `create_users_table.php` re-runs only the tests that queried the `users` table.\n- **Inertia pages** under `resources/js/Pages` re-run only the tests that server-side-rendered them.\n- **Shared JS components** under `resources/js/Components`, `Layouts`, and friends re-run only the tests whose pages import them — Pest walks Vite's module graph to figure this out.\n- **Blade templates** re-run only the tests that rendered them, including renders triggered by browser tests.\n- **Anything else** — config files, route files, `.env`, files outside the recorded graph — falls through to a broader pattern. Editing `config/app.php` re-runs every test, because Pest can't statically prove which tests depend on it.\n\n## Cosmetic Edits Don't Run Anything\n\nPest normalises file content before comparing, so cosmetic changes don't trigger any tests. PHP files have whitespace, line comments, and docblocks stripped before hashing. Blade strips `{{-- … --}}` comments. JS, TS, Vue, and Svelte files have line and block comments removed too.\n\nThe result: a comment-only edit, a Prettier reformat, a Pint pass, or a README tweak produces an identical hash, and the file never enters the changed set. Zero tests run.\n\n## Modes\n\nPest supports a few flags alongside `--tia`:\n\n| Flag | Behaviour |\n|---|---|\n| `--tia` | Replay if a baseline graph exists, otherwise record. |\n| `--tia --fresh` | Discard any existing graph and re-record from scratch. Use this after large refactors or when the graph feels stale. |\n| `--tia --refetch` | Force a CI baseline fetch even within the 24-hour cooldown after a previous failed fetch.\n\n## Sharing The Baseline From CI\n\nRecording the baseline locally takes minutes on large suites. Instead, you can have CI record it once per merge to `main`, and every developer downloads the result.\n\nWhen Pest detects no local graph (or the local graph is out of date), it uses GitHub's CLI to download the latest successful run of a `tia-baseline.yml` workflow's `pest-tia-baseline` artifact. Pest validates the fetched graph against your project state — if it matches, it's adopted. Otherwise it's discarded and a local rebuild proceeds.\n\nHere's a starter workflow you can drop into `.github/workflows/tia-baseline.yml`:\n\n```yaml\nname: TIA Baseline\non:\n  push: { branches: [main] }\n  schedule: [{ cron: '0 3 * * *' }]\n  workflow_dispatch:\njobs:\n  baseline:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n        with: { fetch-depth: 0 }\n      - uses: shivammathur/setup-php@v2\n        with: { php-version: '8.5', coverage: xdebug }\n      - run: composer install --no-interaction --prefer-dist\n      - run: ./vendor/bin/pest --parallel --tia --coverage\n      - name: Stage baseline for upload\n        shell: bash\n        run: |\n          mkdir -p .pest-tia-baseline\n          cp -R \"$HOME/.pest/tia\"/*/. .pest-tia-baseline/\n      - uses: actions/upload-artifact@v4\n        with:\n          name: pest-tia-baseline\n          path: .pest-tia-baseline/\n          retention-days: 30\n```\n\nAfter CI runs, every developer who runs `pest --tia` for the first time on the repo will download this baseline and start replaying immediately, paying no record cost.\n\n## Storage\n\nPest stores its state at `~/.pest/tia/<project-key>/`, where the project key is derived from your normalised git remote URL — so `git@github.com:foo/bar.git` and `https://github.com/foo/bar` produce the same key. A non-git project falls back to a hash of the project's absolute path.\n\nSharing state per remote URL means multiple worktrees of the same repository share one cache, while unrelated projects on the same machine stay isolated.\n\n## Custom Watch Patterns\n\nIf your project has a directory layout that doesn't match the framework defaults, you can register custom watch patterns in `tests/Pest.php`:\n\n```php\npest()->tia()->watch([\n    'config/billing/**/*.php' => ['tests/Feature/Billing'],\n\n    //\n]);\n```\n\nEach glob maps to a list of test directories; whenever a matching file changes, every test under those directories is invalidated. Use this when you have specific test directories that genuinely depend on a file Pest can't see otherwise.\n\n---\n\nNow that you've learned how to use Test Impact Analysis to speed up your test suite, let's discuss how to integrate Pest with your continuous integration workflow: [Continuous Integration](/docs/continuous-integration)\n\n\n---\n\n## Validation Testing validation\nValidation | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/validation\n\n## Testing validation\n\nLivewire provides useful testing utilities for validation scenarios, such as the `assertHasErrors()` method.\n\nBelow is a basic test case that ensures validation errors are thrown if no input is set for the `title` property:\n\n```php\n<?php\n\nnamespace Tests\\Feature\\Livewire;\n\nuse App\\Livewire\\CreatePost;\nuse Livewire\\Livewire;\nuse Tests\\TestCase;\n\nclass CreatePostTest extends TestCase\n{\n    public function test_cant_create_post_without_title()\n    {\n        Livewire::test(CreatePost::class)\n            ->set('content', 'Sample content...')\n            ->call('save')\n            ->assertHasErrors('title');\n    }\n}\n```\n\nIn addition to testing the presence of errors, `assertHasErrors` allows you to also narrow down the assertion to specific rules by passing the rules to assert against as the second argument to the method:\n\n```php\npublic function test_cant_create_post_with_title_shorter_than_3_characters()\n{\n    Livewire::test(CreatePost::class)\n        ->set('title', 'Sa')\n        ->set('content', 'Sample content...')\n        ->call('save')\n        ->assertHasErrors(['title' => ['min:3']]);\n}\n```\n\nYou can also assert the presence of validation errors for multiple properties at the same time:\n\n```php\npublic function test_cant_create_post_without_title_and_content()\n{\n    Livewire::test(CreatePost::class)\n        ->call('save')\n        ->assertHasErrors(['title', 'content']);\n}\n```\n\nFor more information on other testing utilities provided by Livewire, check out the [testing documentation](/docs/4.x/testing).\n\n---\n\n## Forms See also\nForms | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/forms\n\n## See also\n\n- **[Validation](/docs/4.x/validation)** — Validate form inputs with real-time feedback\n- **[wire:model](/docs/4.x/wire-model)** — Bind form inputs to component properties\n- **[File Uploads](/docs/4.x/uploads)** — Handle file uploads in forms\n- **[Actions](/docs/4.x/actions)** — Process form submissions with actions\n- **[Loading States](/docs/4.x/loading-states)** — Show loading indicators during form submission\n\n---\n\n## Browser Testing assertButtonDisabled\nBrowser Testing | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/browser-testing.md\n\n\n### assertButtonDisabled\n\nThe `assertButtonDisabled` method asserts that the given button is disabled:\n\n```php\n$page->assertButtonDisabled('Submit');\n```\n\n## URL Assertions\n\n---\n\n## Lifecycle Hooks Using hooks inside a form object\nLifecycle Hooks | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/lifecycle-hooks\n\n## Using hooks inside a form object\n\nForm objects in Livewire support property update hooks. These hooks work similarly to [component update hooks](#update), letting you perform actions when properties in the form object change.\n\nBelow is an example of a component using a `PostForm` form object:\n\n```php\n<?php // resources/views/components/post/⚡create.blade.php\n\nuse Livewire\\Component;\n\nnew class extends Component {\n    public PostForm $form;\n\n    // ...\n};\n```\n\nHere's the `PostForm` form object containing all the available hooks:\n\n```php\nnamespace App\\Livewire\\Forms;\n\nuse Livewire\\Attributes\\Validate;\nuse Livewire\\Form;\n\nclass PostForm extends Form\n{\n    public $title = '';\n\n    public $tags = [];\n\n    public function updating($property, $value)\n    {\n        // ...\n    }\n\n    public function updated($property, $value)\n    {\n        // ...\n    }\n\n    public function updatingTitle($value)\n    {\n        // ...\n    }\n\n    public function updatedTitle($value)\n    {\n        // ...\n    }\n\n    public function updatingTags($value, $key)\n    {\n        // ...\n    }\n\n    public function updatedTags($value, $key)\n    {\n        // ...\n    }\n\n    // ...\n}\n```\n\n---\n\n## Filtering Tests `only()`\nFiltering Tests | pestphp/pest@4.x | Source: https://github.com/pestphp/docs/blob/4.x/filtering-tests.md\n\n\n### `only()`\n\nDuring development, you may want to focus on running specific tests while excluding all others. Pest provides two ways to do this: running only tests in a specific file, or running only a specific test within a file.\n\n#### Running Only Tests in a File\n\nWhen working on a specific feature, you can mark all tests in a file to run exclusively by calling the `pest()->only()` function at the top of your test file:\n\n```php\n<?php\n\npest()->only();\n\ntest('first test', function () {\n    // This will run\n});\n\ntest('second test', function () {\n    // This will also run\n});\n```\n\nAll tests in files with `pest()->only()` will run, while tests in other files will be skipped.\n\n#### Running a Single Test\n\nTo run only a specific test within a file, chain the `->only()` method to the test:\n\n```php\ntest('sum', function () {\n  $result = sum(1, 2);\n\n  expect($result)->toBe(3);\n})->only();\n\ntest('another test', function () {\n  // This will be skipped\n});\n```\n\n---\n\nAs your codebase grows, manually running your tests with filtering can become tedious. That's where skipping tests comes in. Skipping tests is a useful feature that allows developers to exclude specific tests from the test suite temporarily without deleting them entirely: [Skipping Tests →](/docs/skipping-tests)\n\n---\n\n## Validation Form Request Validation Creating Form Requests Customizing the Redirect Location\nValidation | laravel/framework@12.x | Source: https://github.com/laravel/docs/blob/12.x/validation.md\n\n\n#### Customizing the Redirect Location\n\nWhen form request validation fails, a redirect response will be generated to send the user back to their previous location. However, you are free to customize this behavior. To do so, define a `$redirect` property on your form request:\n\n```php\n/**\n * The URI that users should be redirected to if validation fails.\n *\n * @var string\n */\nprotected $redirect = '/dashboard';\n```\n\nOr, if you would like to redirect users to a named route, you may define a `$redirectRoute` property instead:\n\n```php\n/**\n * The route that users should be redirected to if validation fails.\n *\n * @var string\n */\nprotected $redirectRoute = 'dashboard';\n```\n\n---\n\n## Testing All available testing methods\nTesting | livewire/livewire@4.x | Source: https://livewire.laravel.com/docs/4.x/testing\n\n## All available testing methods\n\nBelow is a comprehensive reference of every Livewire testing method available to you:\n\n### Setup methods\n\n| Method                                                  | Description                                                                                |\n|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|\n| `Livewire::test('post.create')`                      | Test the `post.create` component |\n| `Livewire::test(UpdatePost::class, ['post' => $post])`                      | Test the `UpdatePost` component with parameters passed to `mount()` |\n| `Livewire::actingAs($user)`                      | Set the authenticated user for the test |\n| `Livewire::withQueryParams(['search' => '...'])`                      | Set URL query parameters (ex. `?search=...`) |\n| `Livewire::withCookie('name', 'value')`                      | Set a cookie for the test |\n| `Livewire::withCookies(['color' => 'blue', 'name' => 'Taylor'])`                      | Set multiple cookies |\n| `Livewire::withHeaders(['X-Header' => 'value'])`                      | Set custom headers |\n| `Livewire::withoutLazyLoading()`                      | Disable lazy loading for all components in this test |\n\n### Interacting with components\n\n| Method                                                  | Description                                                                                |\n|---------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|\n| `set('title', '...')`                      | Set the `title` property to the provided value |\n| `set(['title' => '...', 'content' => '...'])`                      | Set multiple properties using an array |\n| `toggle('sortAsc')`                      | Toggle a boolean property between `true` and `false`  |\n| `call('save')`                      | Call the `save` action/method |\n| `call('remove', $postId)`                      | Call a method with parameters |\n| `refresh()`                      | Trigger a component re-render |\n| `dispatch('post-created')`                      | Dispatch an event from the component  |\n| `dispatch('post-created', postId: $post->id)`                      | Dispatch an event with parameters |\n\n### Assertions\n\n| Method                                                | Description                                                                                |\n|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `assertSet('title', '...')`                           | Assert that a property equals the provided value                                                                                |\n| `assertNotSet('title', '...')`                        | Assert that a property does not equal the provided value                                                                                |\n| `assertCount('posts', 3)`                             | Assert that a property contains 3 items                                                                                |\n| `assertSee('...')`                             | Assert that the rendered HTML contains the provided text                                                                                |\n| `assertDontSee('...')`                         | Assert that the rendered HTML does not contain the provided text                                                                                |\n| `assertSeeHtml('<div>...</div>')`                     | Assert that raw HTML is present in the rendered output |\n| `assertDontSeeHtml('<div>...</div>')`                 | Assert that raw HTML is not present in the rendered output                                                                                |\n| `assertSeeInOrder(['first', 'second'])`                    | Assert that strings appear in order in the rendered output                                                                                |\n| `assertDispatched('post-created')`                    | Assert that an event was dispatched                                                                                |\n| `assertNotDispatched('post-created')`                 | Assert that an event was not dispatched                                                                                |\n| `assertHasErrors('title')`                            | Assert that validation failed for a property                                                                                |\n| `assertHasErrors(['title' => ['required', 'min:6']])`   | Assert that specific validation rules failed                                                                                |\n| `assertHasNoErrors('title')`                          | Assert that there are no validation errors for a property                                                                                |\n| `assertRedirect()`                                    | Assert that a redirect was triggered                                                                                |\n| `assertRedirect('/posts')`                            | Assert a redirect to a specific URL                                                                                |\n| `assertRedirectToRoute('posts.index')`       | Assert a redirect to a named route                                                                                |\n| `assertNoRedirect()`                                  | Assert that no redirect was triggered                                                                                |\n| `assertViewHas('posts')`                              | Assert that data was passed to the view                                                                                |\n| `assertViewHas('postCount', 3)`                       | Assert that view data has a specific value                                                                                |\n| `assertViewHas('posts', function ($posts) { ... })`   | Assert view data passes custom validation                                                                         |\n| `assertViewIs('livewire.show-posts')`                 | Assert that a specific view was rendered                                                                                |\n| `assertJs(\"alert('...')\")`                            | Assert that a JS expression was evaluated                                                                                |\n| `assertNoJs()`                                        | Assert that no JS was evaluated                                                                                |\n| `assertFileDownloaded()`                              | Assert that a file download was triggered                                                                                |\n| `assertFileDownloaded($filename)`                     | Assert that a specific file was downloaded                                                                                |\n| `assertUnauthorized()`                                | Assert that an authorization exception was thrown (401)                                                                                |\n| `assertForbidden()`                                   | Assert that access was forbidden (403)                                                                                |\n| `assertStatus(500)`                                   | Assert that a specific status code was returned                                                                                |\n\n_[Truncated]_"}]


find app/Livewire/Storefront app/Livewire/Account resources/views/livewire/storefront resources/views/livewire/account -maxdepth 4 -type f | sort


sed -n '1,260p' resources/views/livewire/storefront/checkout/show.blade.php


sed -n '1,220p' app/Livewire/Account/Dashboard.php


/bin/zsh
-lc
sed -n '1,260p' routes/web.php

<?php

use App\Livewire\Admin\Auth\Login as AdminLogin;
use App\Livewire\Admin\Collections\Form as AdminCollectionForm;
use App\Livewire\Admin\Collections\Index as AdminCollectionsIndex;
use App\Livewire\Admin\Inventory\Index as AdminInventoryIndex;
use App\Livewire\Admin\Products\Form as AdminProductForm;
use App\Livewire\Admin\Products\Index as AdminProductsIndex;
use App\Livewire\Storefront\Account\Auth\Login as CustomerLogin;
use App\Livewire\Storefront\Account\Auth\Register as CustomerRegister;
use App\Livewire\Storefront\Cart\Show as StorefrontCartShow;
use App\Livewire\Storefront\Checkout\Show as StorefrontCheckoutShow;
use App\Livewire\Storefront\Collections\Index as StorefrontCollectionsIndex;
use App\Livewire\Storefront\Collections\Show as StorefrontCollectionShow;
use App\Livewire\Storefront\Home as StorefrontHome;
use App\Livewire\Storefront\Pages\Show as StorefrontPageShow;
use App\Livewire\Storefront\Products\Show as StorefrontProductShow;
use App\Livewire\Storefront\Search\Index as StorefrontSearchIndex;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('/', StorefrontHome::class)->name('home');
    Route::livewire('collections', StorefrontCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/{handle}', StorefrontCollectionShow::class)->name('collections.show');
    Route::livewire('products/{handle}', StorefrontProductShow::class)->name('products.show');
    Route::livewire('cart', StorefrontCartShow::class)->name('cart.show');
    Route::livewire('checkout', StorefrontCheckoutShow::class)->name('checkout.show');
    Route::livewire('search', StorefrontSearchIndex::class)->name('search.index');
    Route::livewire('pages/{handle}', StorefrontPageShow::class)->name('pages.show');
});

Route::livewire('admin/login', AdminLogin::class)
    ->middleware('guest')
    ->name('admin.login');

Route::post('admin/logout', function () {
    Auth::guard('web')->logout();

    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect()->route('admin.login');
})->middleware('auth')->name('admin.logout');

Route::middleware(['auth', 'verified', 'admin'])->prefix('admin')->name('admin.')->group(function (): void {
    Route::view('/', 'dashboard')->name('dashboard');
    Route::livewire('products', AdminProductsIndex::class)->name('products.index');
    Route::livewire('products/create', AdminProductForm::class)->name('products.create');
    Route::livewire('products/{product}/edit', AdminProductForm::class)->name('products.edit');
    Route::livewire('inventory', AdminInventoryIndex::class)->name('inventory.index');
    Route::livewire('collections', AdminCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/create', AdminCollectionForm::class)->name('collections.create');
    Route::livewire('collections/{collection}/edit', AdminCollectionForm::class)->name('collections.edit');
});

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('account/login', CustomerLogin::class)
        ->middleware('guest:customer')
        ->name('account.login');

    Route::livewire('account/register', CustomerRegister::class)
        ->middleware('guest:customer')
        ->name('account.register');

    Route::view('account', 'storefront.account.dashboard')
        ->middleware('auth:customer')
        ->name('account.dashboard');
});

Route::redirect('dashboard', 'admin')
    ->middleware(['auth', 'verified'])
    ->name('dashboard');

require __DIR__.'/settings.php';


Output:
Chunk ID: 60ef0a
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 916
Output:
<?php

use App\Livewire\Admin\Auth\Login as AdminLogin;
use App\Livewire\Admin\Collections\Form as AdminCollectionForm;
use App\Livewire\Admin\Collections\Index as AdminCollectionsIndex;
use App\Livewire\Admin\Inventory\Index as AdminInventoryIndex;
use App\Livewire\Admin\Products\Form as AdminProductForm;
use App\Livewire\Admin\Products\Index as AdminProductsIndex;
use App\Livewire\Storefront\Account\Auth\Login as CustomerLogin;
use App\Livewire\Storefront\Account\Auth\Register as CustomerRegister;
use App\Livewire\Storefront\Cart\Show as StorefrontCartShow;
use App\Livewire\Storefront\Checkout\Show as StorefrontCheckoutShow;
use App\Livewire\Storefront\Collections\Index as StorefrontCollectionsIndex;
use App\Livewire\Storefront\Collections\Show as StorefrontCollectionShow;
use App\Livewire\Storefront\Home as StorefrontHome;
use App\Livewire\Storefront\Pages\Show as StorefrontPageShow;
use App\Livewire\Storefront\Products\Show as StorefrontProductShow;
use App\Livewire\Storefront\Search\Index as StorefrontSearchIndex;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('/', StorefrontHome::class)->name('home');
    Route::livewire('collections', StorefrontCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/{handle}', StorefrontCollectionShow::class)->name('collections.show');
    Route::livewire('products/{handle}', StorefrontProductShow::class)->name('products.show');
    Route::livewire('cart', StorefrontCartShow::class)->name('cart.show');
    Route::livewire('checkout', StorefrontCheckoutShow::class)->name('checkout.show');
    Route::livewire('search', StorefrontSearchIndex::class)->name('search.index');
    Route::livewire('pages/{handle}', StorefrontPageShow::class)->name('pages.show');
});

Route::livewire('admin/login', AdminLogin::class)
    ->middleware('guest')
    ->name('admin.login');

Route::post('admin/logout', function () {
    Auth::guard('web')->logout();

    request()->session()->invalidate();
    request()->session()->regenerateToken();

    return redirect()->route('admin.login');
})->middleware('auth')->name('admin.logout');

Route::middleware(['auth', 'verified', 'admin'])->prefix('admin')->name('admin.')->group(function (): void {
    Route::view('/', 'dashboard')->name('dashboard');
    Route::livewire('products', AdminProductsIndex::class)->name('products.index');
    Route::livewire('products/create', AdminProductForm::class)->name('products.create');
    Route::livewire('products/{product}/edit', AdminProductForm::class)->name('products.edit');
    Route::livewire('inventory', AdminInventoryIndex::class)->name('inventory.index');
    Route::livewire('collections', AdminCollectionsIndex::class)->name('collections.index');
    Route::livewire('collections/create', AdminCollectionForm::class)->name('collections.create');
    Route::livewire('collections/{collection}/edit', AdminCollectionForm::class)->name('collections.edit');
});

Route::middleware(['storefront'])->group(function (): void {
    Route::livewire('account/login', CustomerLogin::class)
        ->middleware('guest:customer')
        ->name('account.login');

    Route::livewire('account/register', CustomerRegister::class)
        ->middleware('guest:customer')
        ->name('account.register');

    Route::view('account', 'storefront.account.dashboard')
        ->middleware('auth:customer')
        ->name('account.dashboard');
});

Route::redirect('dashboard', 'admin')
    ->middleware(['auth', 'verified'])
    ->name('dashboard');

require __DIR__.'/settings.php';


sed -n '1,220p' app/Livewire/Account/Dashboard.php

sed: app/Livewire/Account/Dashboard.php: No such file or directory


sed -n '1,260p' resources/views/livewire/storefront/checkout/show.blade.php

    <x-storefront.breadcrumbs :items="[
        ['label' => 'Cart', 'url' => route('cart.show')],
        ['label' => 'Checkout'],
    ]" />

Checkout

                    @foreach (['address' => 'Address', 'shipping' => 'Shipping', 'payment' => 'Payment'] as $key => $label)
                        @php($active = $step === $key || ($key === 'payment' && $step === 'reserved'))

 $active,
                            'border-zinc-200 text-zinc-600 dark:border-zinc-800 dark:text-zinc-400' => ! $active,
                        ])>
                            {{ $label }}

                    @endforeach

            @if (! $cart || $lines->isEmpty())

                    <flux:icon name="shopping-bag" class="mx-auto size-12 text-zinc-400 dark:text-zinc-600" />

Your cart is empty

                    <flux:button :href="route('collections.index')" wire:navigate variant="primary" class="mt-6">
                        Browse products
                    </flux:button>

            @else
                <form wire:submit="saveAddress" class="rounded-lg border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-950">

                            <flux:heading size="lg">Contact and address</flux:heading>
                            <flux:text class="mt-1">Delivery details</flux:text>

                        @if ($checkout?->status !== \App\Enums\CheckoutStatus::Started)
                            <flux:badge color="green">Saved</flux:badge>
                        @endif

                            <flux:input wire:model="email" type="email" label="Email" />
                            <flux:error name="email" />

                        <flux:input wire:model="shippingAddress.first_name" label="First name" />
                        <flux:input wire:model="shippingAddress.last_name" label="Last name" />

                            <flux:input wire:model="shippingAddress.address1" label="Address" />
                            <flux:error name="shippingAddress.address1" />

                            <flux:input wire:model="shippingAddress.address2" label="Apartment, suite, etc." />

                        <flux:input wire:model="shippingAddress.city" label="City" />
                        <flux:input wire:model="shippingAddress.postal_code" label="Postal code" />

                        <flux:input wire:model="shippingAddress.province_code" label="Region code" placeholder="DE-BE" />
                        <flux:select wire:model="shippingAddress.country" label="Country">
                            <flux:select.option value="DE">Germany</flux:select.option>
                            <flux:select.option value="AT">Austria</flux:select.option>
                            <flux:select.option value="CH">Switzerland</flux:select.option>
                        </flux:select>

                    <flux:checkbox wire:model="billingSame" label="Billing address is the same" class="mt-5" />

                        <flux:button type="submit" variant="primary">
                            Continue
                        </flux:button>

                </form>

                            <flux:heading size="lg">Shipping</flux:heading>
                            <flux:text class="mt-1">{{ $requiresShipping ? 'Available rates' : 'Digital delivery' }}<…3380 chars truncated…=== \App\Enums\CheckoutStatus::PaymentSelected)
                            <flux:badge color="green">Reserved</flux:badge>
                        @endif

                    @if ($step === 'address' || $step === 'shipping')

Pending shipping

                    @else

                                <flux:input wire:model="discountCode" label="Discount code" placeholder="SAVE10" />
                                <flux:button type="button" wire:click="applyDiscount" variant="ghost" class="mt-6">
                                    Apply
                                </flux:button>

                            <flux:error name="discountCode" />

                            <flux:select wire:model="paymentMethod" label="Payment method">
                                <flux:select.option value="credit_card">Credit card</flux:select.option>
                                <flux:select.option value="paypal">PayPal</flux:select.option>
                                <flux:select.option value="bank_transfer">Bank transfer</flux:select.option>
                            </flux:select>
                            <flux:error name="paymentMethod" />

                            <flux:button wire:click="selectPaymentMethod" variant="primary" class="w-full">
                                Reserve items
                            </flux:button>

                    @endif

            @endif

Order summary

                @foreach ($lines as $line)

getKey() }}">

                            <flux:icon name="shopping-bag" class="size-5" />

{{ $line->variant->product->title }}

Qty {{ $line->quantity }}

                        <x-storefront.price :amount="$line->line_total_amount" :currency="$cart?->currency ?? data_get($totals, 'currency')" class="justify-end text-sm" />

                @endforeach

                    Subtotal
                    <x-storefront.price :amount="data_get($totals, 'subtotal', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Discount
                    -{{ \App\Support\Money::format((int) data_get($totals, 'discount', 0), data_get($totals, 'currency', $cart?->currency ?? 'EUR')) }}

                    Shipping
                    <x-storefront.price :amount="data_get($totals, 'shipping', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Tax
                    <x-storefront.price :amount="data_get($totals, 'tax', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Total
                    <x-storefront.price :amount="data_get($totals, 'total', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />


find app/Livewire/Storefront app/Livewire/Account resources/views/livewire/storefront resources/views/livewire/account -maxdepth 4 -type f | sort

find: app/Livewire/Account: No such file or directory
find: resources/views/livewire/account: No such file or directory
app/Livewire/Storefront/Account/Auth/Login.php
app/Livewire/Storefront/Account/Auth/Register.php
app/Livewire/Storefront/Cart/Show.php
app/Livewire/Storefront/CartDrawer.php
app/Livewire/Storefront/Checkout/Show.php
app/Livewire/Storefront/Collections/Index.php
app/Livewire/Storefront/Collections/Show.php
app/Livewire/Storefront/Home.php
app/Livewire/Storefront/Pages/Show.php
app/Livewire/Storefront/Products/Show.php
app/Livewire/Storefront/Search/Index.php
resources/views/livewire/storefront/account/auth/login.blade.php
resources/views/livewire/storefront/account/auth/register.blade.php
resources/views/livewire/storefront/cart-drawer.blade.php
resources/views/livewire/storefront/cart/show.blade.php
resources/views/livewire/storefront/checkout/show.blade.php
resources/views/livewire/storefront/collections/index.blade.php
resources/views/livewire/storefront/collections/show.blade.php
resources/views/livewire/storefront/home.blade.php
resources/views/livewire/storefront/pages/show.blade.php
resources/views/livewire/storefront/products/show.blade.php
resources/views/livewire/storefront/search/index.blade.php


Output:
Chunk ID: a3a617
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 311
Output:
find: app/Livewire/Account: No such file or directory
find: resources/views/livewire/account: No such file or directory
app/Livewire/Storefront/Account/Auth/Login.php
app/Livewire/Storefront/Account/Auth/Register.php
app/Livewire/Storefront/Cart/Show.php
app/Livewire/Storefront/CartDrawer.php
app/Livewire/Storefront/Checkout/Show.php
app/Livewire/Storefront/Collections/Index.php
app/Livewire/Storefront/Collections/Show.php
app/Livewire/Storefront/Home.php
app/Livewire/Storefront/Pages/Show.php
app/Livewire/Storefront/Products/Show.php
app/Livewire/Storefront/Search/Index.php
resources/views/livewire/storefront/account/auth/login.blade.php
resources/views/livewire/storefront/account/auth/register.blade.php
resources/views/livewire/storefront/cart-drawer.blade.php
resources/views/livewire/storefront/cart/show.blade.php
resources/views/livewire/storefront/checkout/show.blade.php
resources/views/livewire/storefront/collections/index.blade.php
resources/views/livewire/storefront/collections/show.blade.php
resources/views/livewire/storefront/home.blade.php
resources/views/livewire/storefront/pages/show.blade.php
resources/views/livewire/storefront/products/show.blade.php
resources/views/livewire/storefront/search/index.blade.php


Output:
Chunk ID: bb9b7c
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 3345
Output:

    <x-storefront.breadcrumbs :items="[
        ['label' => 'Cart', 'url' => route('cart.show')],
        ['label' => 'Checkout'],
    ]" />

Checkout

                    @foreach (['address' => 'Address', 'shipping' => 'Shipping', 'payment' => 'Payment'] as $key => $label)
                        @php($active = $step === $key || ($key === 'payment' && $step === 'reserved'))

 $active,
                            'border-zinc-200 text-zinc-600 dark:border-zinc-800 dark:text-zinc-400' => ! $active,
                        ])>
                            {{ $label }}

                    @endforeach

            @if (! $cart || $lines->isEmpty())

                    <flux:icon name="shopping-bag" class="mx-auto size-12 text-zinc-400 dark:text-zinc-600" />

Your cart is empty

                    <flux:button :href="route('collections.index')" wire:navigate variant="primary" class="mt-6">
                        Browse products
                    </flux:button>

            @else
                <form wire:submit="saveAddress" class="rounded-lg border border-zinc-200 bg-white p-5 dark:border-zinc-800 dark:bg-zinc-950">

                            <flux:heading size="lg">Contact and address</flux:heading>
                            <flux:text class="mt-1">Delivery details</flux:text>

                        @if ($checkout?->status !== \App\Enums\CheckoutStatus::Started)
                            <flux:badge color="green">Saved</flux:badge>
                        @endif

                            <flux:input wire:model="email" type="email" label="Email" />
                            <flux:error name="email" />

                        <flux:input wire:model="shippingAddress.first_name" label="First name" />
                        <flux:input wire:model="shippingAddress.last_name" label="Last name" />

                            <flux:input wire:model="shippingAddress.address1" label="Address" />
                            <flux:error name="shippingAddress.address1" />

                            <flux:input wire:model="shippingAddress.address2" label="Apartment, suite, etc." />

                        <flux:input wire:model="shippingAddress.city" label="City" />
                        <flux:input wire:model="shippingAddress.postal_code" label="Postal code" />

                        <flux:input wire:model="shippingAddress.province_code" label="Region code" placeholder="DE-BE" />
                        <flux:select wire:model="shippingAddress.country" label="Country">
                            <flux:select.option value="DE">Germany</flux:select.option>
                            <flux:select.option value="AT">Austria</flux:select.option>
                            <flux:select.option value="CH">Switzerland</flux:select.option>
                        </flux:select>

                    <flux:checkbox wire:model="billingSame" label="Billing address is the same" class="mt-5" />

                        <flux:button type="submit" variant="primary">
                            Continue
                        </flux:button>

                </form>

                            <flux:heading size="lg">Shipping</flux:heading>
                            <flux:text class="mt-1">{{ $requiresShipping ? 'Available rates' : 'Digital delivery' }}</flux:text>

                        @if ($checkout?->status === \App\Enums\CheckoutStatus::ShippingSelected || $checkout?->status === \App\Enums\CheckoutStatus::PaymentSelected)
                            <flux:badge color="green">Selected</flux:badge>
                        @endif

                    @if ($step === 'address')

Pending address

                    @elseif (! $requiresShipping)

                            Digital delivery
                            0.00

                    @else

                            @forelse ($rates as $rate)
                                @php($selected = (int) $selectedShippingRateId === (int) $rate->getKey())
                                <button
                                    type="button"
                                    wire:click="$set('selectedShippingRateId', {{ $rate->getKey() }})"
                                    @class([
                                        'flex w-full items-center justify-between gap-4 rounded-md border px-4 py-3 text-left transition',
                                        'border-blue-700 bg-blue-50 dark:border-blue-300 dark:bg-blue-950' => $selected,
                                        'border-zinc-200 hover:border-zinc-400 dark:border-zinc-800 dark:hover:border-zinc-600' => ! $selected,
                                    ])
                                >
                                    {{ $rate->name }}
                                    <x-storefront.price :amount="data_get($rateAmounts, $rate->getKey(), 0)" :currency="$cart->currency" />
                                </button>
                            @empty

No rates are available for this address.

                            @endforelse

                        <flux:error name="selectedShippingRateId" />
                    @endif

                    @if ($step !== 'address')

                            <flux:button wire:click="selectShippingMethod" variant="primary" :disabled="$requiresShipping && ! $selectedShippingRateId">
                                Continue
                            </flux:button>

                    @endif

                            <flux:heading size="lg">Payment</flux:heading>
                            <flux:text class="mt-1">Method</flux:text>

                        @if ($checkout?->status === \App\Enums\CheckoutStatus::PaymentSelected)
                            <flux:badge color="green">Reserved</flux:badge>
                        @endif

                    @if ($step === 'address' || $step === 'shipping')

Pending shipping

                    @else

                                <flux:input wire:model="discountCode" label="Discount code" placeholder="SAVE10" />
                                <flux:button type="button" wire:click="applyDiscount" variant="ghost" class="mt-6">
                                    Apply
                                </flux:button>

                            <flux:error name="discountCode" />

                            <flux:select wire:model="paymentMethod" label="Payment method">
                                <flux:select.option value="credit_card">Credit card</flux:select.option>
                                <flux:select.option value="paypal">PayPal</flux:select.option>
                                <flux:select.option value="bank_transfer">Bank transfer</flux:select.option>
                            </flux:select>
                            <flux:error name="paymentMethod" />

                            <flux:button wire:click="selectPaymentMethod" variant="primary" class="w-full">
                                Reserve items
                            </flux:button>

                    @endif

            @endif

Order summary

                @foreach ($lines as $line)

getKey() }}">

                            <flux:icon name="shopping-bag" class="size-5" />

{{ $line->variant->product->title }}

Qty {{ $line->quantity }}

                        <x-storefront.price :amount="$line->line_total_amount" :currency="$cart?->currency ?? data_get($totals, 'currency')" class="justify-end text-sm" />

                @endforeach

                    Subtotal
                    <x-storefront.price :amount="data_get($totals, 'subtotal', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Discount
                    -{{ \App\Support\Money::format((int) data_get($totals, 'discount', 0), data_get($totals, 'currency', $cart?->currency ?? 'EUR')) }}

                    Shipping
                    <x-storefront.price :amount="data_get($totals, 'shipping', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Tax
                    <x-storefront.price :amount="data_get($totals, 'tax', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />

                    Total
                    <x-storefront.price :amount="data_get($totals, 'total', 0)" :currency="data_get($totals, 'currency', $cart?->currency ?? 'EUR')" />


Output:
Chunk ID: 3dc1f5
Wall time: 0.0000 seconds
Process exited with code 1
Original token count: 17
Output:
sed: app/Livewire/Account/Dashboard.php: No such file or directory


sed -n '1,220p' resources/views/storefront/account/dashboard.blade.php


sed -n '1,240p' app/Livewire/Storefront/Account/Auth/Login.php


sed -n '1,220p' resources/views/livewire/storefront/account/auth/login.blade.php


sed -n '1,220p' resources/views/layouts/storefront.blade.php


sed -n '1,220p' resources/views/storefront/account/dashboard.blade.php

<x-layouts::auth>
    <div class="flex flex-col gap-4 text-center">
        <x-auth-header :title="__('Account')" :description="__('You are logged in to your customer account.')" />
    </div>
</x-layouts::auth>


sed -n '1,220p' resources/views/livewire/storefront/account/auth/login.blade.php

    <x-auth-header :title="__('Log in')" :description="__('Access your orders and saved addresses')" />

    <form wire:submit="login" class="flex flex-col gap-6">
        <flux:input
            wire:model="email"
            :label="__('Email address')"
            type="email"
            required
            autofocus
            autocomplete="email"
            placeholder="customer@acme.test"
        />

        <flux:input
            wire:model="password"
            :label="__('Password')"
            type="password"
            required
            autocomplete="current-password"
            :placeholder="__('Password')"
            viewable
        />

        <flux:checkbox wire:model="remember" :label="__('Remember me')" />

        <flux:button variant="primary" type="submit" class="w-full" data-test="customer-login-button">
            {{ __('Log in') }}
        </flux:button>
    </form>

        {{ __('New customer?') }}
        <flux:link :href="route('account.register')" wire:navigate>{{ __('Create an account') }}</flux:link>


sed -n '1,240p' app/Livewire/Storefront/Account/Auth/Login.php

<?php

namespace App\Livewire\Storefront\Account\Auth;

use App\Models\Customer;
use App\Models\Store;
use App\Services\CartService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Validation\ValidationException;
use Livewire\Component;

class Login extends Component
{
    public int $storeId;

    public string $email = '';

    public string $password = '';

    public bool $remember = false;

    public function mount(): void
    {
        $store = app('current_store');

        abort_unless($store instanceof Store, 404);

        $this->storeId = $store->getKey();
    }

    public function login(): void
    {
        $this->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'string'],
            'remember' => ['boolean'],
        ]);

        $key = 'customer-login:'.request()->ip();

        if (RateLimiter::tooManyAttempts($key, 5)) {
            throw ValidationException::withMessages([
                'email' => __('Too many attempts. Try again in :seconds seconds.', [
                    'seconds' => RateLimiter::availableIn($key),
                ]),
            ]);
        }

        app()->instance('current_store', Store::query()->findOrFail($this->storeId));

        if (! Auth::guard('customer')->attempt([
            'email' => $this->email,
            'password' => $this->password,
        ], $this->remember)) {
            RateLimiter::hit($key, 60);

            throw ValidationException::withMessages([
                'email' => __('Invalid credentials'),
            ]);
        }

        RateLimiter::clear($key);

        if (request()->hasSession()) {
            request()->session()->regenerate();
        }

        $customer = Auth::guard('customer')->user();

        if ($customer instanceof Customer && session()->has('cart_id')) {
            app(CartService::class)->getOrCreateForSession(Store::query()->findOrFail($this->storeId), $customer);
        }

        $this->redirectRoute('account.dashboard', navigate: true);
    }

    public function render(): mixed
    {
        return view('livewire.storefront.account.auth.login')
            ->layout('layouts.auth');
    }
}


sed -n '1,220p' resources/views/layouts/storefront.blade.php

<!DOCTYPE html>
getLocale()) }}">

        @include('partials.head')

        @php($store = app()->bound('current_store') ? app('current_store') : null)
        @php($announcement = data_get($themeSettings ?? [], 'announcement', []))
        @php($mainLinks = ($mainNavigation ?? []) !== [] ? $mainNavigation : [['label' => 'Collections', 'url' => route('collections.index'), 'external' => false], ['label' => 'Search', 'url' => route('search.index'), 'external' => false]])
        @php($footerLinks = ($footerNavigation ?? []) !== [] ? $footerNavigation : [['label' => 'Collections', 'url' => route('collections.index'), 'external' => false], ['label' => 'Search', 'url' => route('search.index'), 'external' => false]])

            Skip to main content

        @if (data_get($announcement, 'enabled', false))

                @if (data_get($announcement, 'url'))

                        {{ data_get($announcement, 'text') }}

                @else
                    {{ data_get($announcement, 'text') }}
                @endif

        @endif

         data_get($themeSettings ?? [], 'header.sticky', true),
        ])>

                    {{ $store?->name ?? config('app.name') }}

                    @foreach ($mainLinks as $item)

                            {{ $item['label'] }}

                    @endforeach

                    <flux:button :href="route('search.index')" wire:navigate variant="subtle" icon="magnifying-glass" aria-label="Search" />
                    <flux:button :href="route('account.dashboard')" wire:navigate variant="subtle" icon="user" aria-label="Account" />
                    <flux:modal.trigger name="cart-drawer">
                        <flux:button variant="subtle" icon="shopping-bag" aria-label="Cart" />
                    </flux:modal.trigger>

        <livewire:storefront.cart-drawer />

            {{ $slot }}

{{ $store?->name ?? config('app.name') }}

{{ data_get($themeSettings ?? [], 'footer.tagline') }}

Shop

                        @foreach ($footerLinks as $item)

                                {{ $item['label'] }}

                        @endforeach

Customer

                        Account
                        About

        @fluxScripts


Output:
Chunk ID: 6c5f46
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 53
Output:
<x-layouts::auth>
    <div class="flex flex-col gap-4 text-center">
        <x-auth-header :title="__('Account')" :description="__('You are logged in to your customer account.')" />
    </div>
</x-layouts::auth>