Giter Site home page Giter Site logo

missing-livewire-assertions's Introduction

CleanShot 2023-02-14 at 17 17 03@2x

This Package Adds Missing Livewire Test Assertions

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

This package adds some nice new Livewire assertions which I was missing while testing my applications using Livewire. If you want to know more about WHY I needed them, check out my blog article.

➡️ Version 2.0 of this package only supports Livewire 3. Please use a lower version of this package for other Livewire versions.

Installation

You can install the package via composer:

composer require christophrumpel/missing-livewire-assertions

Usage

The new assertions get added automatically, so you can use them immediately.

Check if a Livewire property is wired to an HTML field

Livewire::test(FeedbackForm::class)
    ->assertPropertyWired('email');

It looks for a string like wire:model="email" in your component's view file. It also detects variations like wire:model.live="email", wire:model.lazy="email", wire:model.debounce="email", wire:model.lazy.10s="email" or wire:model.debounce.500ms="email".

Check if a Livewire method is wired to an HTML field

Livewire::test(FeedbackForm::class)
    ->assertMethodWired('submit');

It looks for a string like wire:click="submit" in your component's view file.

Check if a Livewire magic action is wired to an HTML field

Livewire::test(FeedbackForm::class)
    ->assertMethodWired('$toggle(\'sortAsc\')');

Check if a generic Livewire method is wired to an HTML field

Livewire::test(FeedbackForm::class)
    ->assertMethodWiredToAction('mouseenter', 'enter');

It looks for a string like wire:mouseenter="enter" in your component's view file. Also, note that it can also look for any events, like wire:keydown or wire:custom-event.

It looks for a string like wire:click="$refresh", wire:click="$toggle('sortAsc'), $dispatch('post-created'), along with all other magic actions. When testing for magic actions, you must escape single quotes like shown above.

Check if a Livewire method is wired to an HTML form

Livewire::test(FeedbackForm::class)
    ->assertMethodWiredToForm('upload');

It looks for a string like wire:submit.prevent="upload" in your component's view file.

Check if a Livewire method is wired to a specific javascript event

Livewire::test(FeedbackForm::class)
    ->assertMethodWiredToEvent('setValue', 'change');

It looks for a string like wire:change.debounce.150ms="setValue" in your component's view file.

You can also check for actions without any additional modifiers:

Livewire::test(FeedbackForm::class)
    ->assertMethodWiredToEventWithoutModifiers('reset', 'keyup');

This will match wire:keyup="reset", but not wire:keyup.escape="reset". You could match that with

Livewire::test(FeedbackForm::class)
    ->assertMethodWiredToEventWithoutModifiers('reset', 'keyup.escape');

Check if a Livewire component contains another Livewire component

Livewire::test(FeedbackForm::class)
    ->assertContainsLivewireComponent(CategoryList::class);

You can use the component tag name as well:

Livewire::test(FeedbackForm::class)
    ->assertContainsLivewireComponent('category-list');

Check if a Livewire component contains a Blade component

Livewire::test(FeedbackForm::class)
    ->assertContainsBladeComponent(Button::class);

You can use the component tag name as well:

Livewire::test(FeedbackForm::class)
    ->assertContainsBladeComponent('button');

Check to see if a string comes before another string

Livewire::test(FeedbackForm::class)
    ->assertSeeBefore('first string', 'second string');

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

missing-livewire-assertions's People

Contributors

abenerd avatar alexmanase avatar bretterer avatar cheesegrits avatar christophrumpel avatar dostrog avatar gertjanroke avatar jonjakoblich avatar joshualukecaine avatar laravel-shift avatar leganz avatar michael-rubel avatar mpociot avatar nuernbergera avatar peterfox avatar titantwentyone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

missing-livewire-assertions's Issues

assertContainsLivewireComponent fails when components are not in main Livewire namespace

When testing against a component which is in a subdirectory of the main Livewire namespace, assertContainsLivewireComponent fails

namespace App\Http\Livewire\Components;

use Livewire\Component;

class MyComponent extends Component
{
   //...
}

test:

Livewire::test(MyParentComponent::class)
    ->assertContainsLivewireComponent(MyComponent::class);

Error comes back:

matches PCRE pattern "/@livewire\('my-component'|<livewire\:my-component/".

The following is okay however:

Livewire::test(MyParentComponent::class)
    ->assertContainsLivewireComponent('components.my-component);

Tried to look at a fix. Since assertContainsLivewireComponent uses basename() to strip out the class, I used the following (possibly ugly) fix:

        return function (string $componentNeedleClass) {
            $componentNeedle = Str::of($componentNeedleClass)
                ->remove('App\Http\Livewire\\')
                ->explode('\\')
                ->map(function($item)
                {
                    return Str::kebab($item);
                })
                ->implode('.');
             ...

I wanted to provide a pull request but, while this works me, your tests fail. I guess this is down to the fact that the test components are not in App\Http\Livewire. I'm no Livewire aficionado so I wasn't sure how to resolve this! Happy to help if I can however!

Can't assert methods which are attached to actions other than `click`

It would be great to be able to assert methods which are wired to actions other than click. I will often attach a method to a change event on a select dropdown, as follows.

<select wire:change="setValue($event.target.value)">
    <option value='1'>Value 1</option>
    <option value='2'>Value 2</option>
</select>

Two thoughts on how this could be implemented

  • Change assertMethodWired to look for any string after wire:, not just click.
  • Add a new method something like assertMethodWiredToAction('methodName', 'action')

assertPropertyWired and assertMethodWired only detect double quotation marks

Where we have:

<input type='text' wire:model='property'/>
<button wire:click='method'>Do it!</button>

and test with:

Livewire::test(MyComponent::class)
    ->assertPropertyWired('property')
    ->assertMethodWired('method');

assertPropertyWired and assertMethodWired will both fail as it it is testing against double quotes rather than double quotes and single quotes.

Failed asserting that '<div wire:id="fjmdPc9adH8Od6DRxZl6">\n
          <input type='text' wire:model="property"/>\n    <--- fixed this to pass
          <button wire:click='method'>Do it!</button>\n
  </div>' matches PCRE pattern "/wire:click(\.(prevent))*="method(\s*\(.+\)\s*)?\s*"/".

I'll try and park some time and amend the regex for a PR.

Livewire Testable not found

Class "Livewire\Features\SupportTesting\Testable" not found

 at vendor/christophrumpel/missing-livewire-assertions/src/MissingLivewireAssertionsServiceProvider.php:19
     15▕     }
     16▕
     17▕     public function bootingPackage(): void
     18▕     {
  ➜  19▕         Testable::mixin(new CustomLivewireAssertionsMixin());
     20▕     }
     21▕ }
     22▕

Error when installing package in latest Laravel Jetstream install.

Prepare it for Laravel 10

➜  pest-course git:(devel) ✗ composer require christophrumpel/missing-livewire-assertions --dev
./composer.json has been updated
Running composer update christophrumpel/missing-livewire-assertions
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - christophrumpel/missing-livewire-assertions v0.1.0 requires illuminate/contracts ^8.37 -> found illuminate/contracts[v8.37.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
    - christophrumpel/missing-livewire-assertions[v0.1.1, ..., v0.4.0] require illuminate/support ^8.0 -> found illuminate/support[v8.0.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
    - christophrumpel/missing-livewire-assertions[dev-production, v0.5.0, ..., v0.7.0] require illuminate/support ^9.0 -> found illuminate/support[v9.0.0-beta.1, ..., 9.x-dev] but these were not loaded, likely because it conflicts with another require.
    - Root composer.json requires christophrumpel/missing-livewire-assertions * -> satisfiable by christophrumpel/missing-livewire-assertions[dev-production, v0.1.0, ..., v0.7.0, 9999999-dev].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require christophrumpel/missing-livewire-assertions:*" to figure out if any version is installable, or "composer require christophrumpel/missing-livewire-assertions:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.

(new feat/proposal) Assert missing wired props/methods

In Christophrumpel\MissingLivewireAssertions\CustomLivewireAssertionsMixin.php would be nice to have the opposite functions to test that a property/method is NOT wired. This can happen under several conditions, one being a form that will be loaded according to a property's value.

A working solution for this would be to add another method that asserts it does not match the RegExp given, such as:

public function assertPropertyNotWired(): Closure
    {
        return function (string $property) {
            PHPUnit::assertDoesNotMatchRegularExpression(
                '/wire:model(\.(defer|(lazy|debounce)(\.\d+?(ms|s)|)))*=(?<q>"|\')'.$property.'(\k\'q\')/',
                $this->stripOutInitialData($this->lastRenderedDom)
            );

            return $this;
        };
    }

The same could be made available for every assertion method using PHPUnit::assertMatchesRegularExpression

Livewire 3

Hey, firstly thanks for the great package.

I started a project recently using Livewire 3 and noticed that the assertions don't work there.

I have fixed the package locally so that it all works with Livewire 3. Can I make a PR or something? when I try to on Github Desktop I get an error.

image

Apologies if this is silly question, first time attempting to contribute to anything like this.

Cannot test for magic actions

I ran into an issue trying to assert that a property was wired in my component, but via a magic action.

<a href="#" wire:click.prevent="$toggle('changeUser')">Change assigned user</a>

In my Livewire component changeUser is a property with a boolean value. I tried the following tests and both failed to match for a PCRE pattern.

Livewire::test(AssignUser::class,[
        'maintenanceRequest' => $maintenanceRequest,
    ])
        ->assertOk()
        ->assertMethodWired('$toggle(\'changeUser\')');
Livewire::test(AssignUser::class,[
        'maintenanceRequest' => $maintenanceRequest,
    ])
        ->assertOk()
        ->assertMethodWired(changeUser');

I think this could be accomplished by modifying the regular expression in the methods assertMethodWired and assertMethodNotWired to allow for magic actions.

`assertMethodWired` does not work with `wire:click.prevent`

When we use something like this (pay attention on .prevent with click):

<x-jet-danger-button wire:key="del-actions" wire:click.prevent="delete" onclick="confirm('Remove car \\'{{ $car->name }}\\'.\nAre you sure?') || event.stopImmediatePropagation()" wire:loading.attr="disabled">
    <x-far-trash-alt wire:loading.remove wire:target="delete" class="-ml-0.5 mr-2 h-4 w-4" />
    <x-fas-spinner wire:loading wire:target="delete" class="-ml-0.5 mr-2 h-4 w-4 animate-spin" />
    {{ __('Delete car') }}
</x-jet-danger-button>

assertion

...
$component->assertMethodWired('delete');
...

does not work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.