Skip to content

Commit

Permalink
Introduced DuskModalMacros for better testing
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalbaljet committed Nov 6, 2024
1 parent 2106d4c commit 059e1ca
Show file tree
Hide file tree
Showing 21 changed files with 114 additions and 66 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"require-dev": {
"larastan/larastan": "^2.9",
"laravel/dusk": "^8.2",
"laravel/pint": "^1.14",
"orchestra/testbench": "^8.23||^9.1",
"rector/rector": "^1.0.3"
Expand Down Expand Up @@ -68,4 +69,4 @@
},
"minimum-stability": "dev",
"prefer-stable": true
}
}
14 changes: 7 additions & 7 deletions demo-app/tests/Browser/BaseRouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public function it_can_open_a_modal_with_a_base_route()
->waitForFirstUser()
->assertSeeIn('.im-modal-content', 'Edit User')
->assertPresent("@edit-user-{$firstUser->id}")
->click('.im-close-button')
->waitUntilMissing('.im-dialog')
->clickModalCloseButton()
->waitUntilMissingModal()
->waitForLocation('/users');
});
}
Expand All @@ -36,13 +36,13 @@ public function it_can_open_a_stacked_modal_on_top_of_a_modal_with_a_base_route(
$browser->visit("/users/{$firstUser->id}/edit")
->waitForTextIn('.im-modal-content', 'Edit User')
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->waitForModal(1)
->assertRouteIs('users.edit', ['user' => $firstUser->id])
->within('.im-dialog[data-inertiaui-modal-index="1"]', function (Browser $browser) use ($newRoleName) {
->withinModal(function (Browser $browser) use ($newRoleName) {
$browser->type('name', $newRoleName)->press('Save');
})
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) use ($newRoleName) {
}, 1)
->waitUntilMissingModal(1)
->withinModal(function (Browser $browser) use ($newRoleName) {
$newRole = Role::where('name', $newRoleName)->firstOr(
fn () => $this->fail('New role was not saved.')
);
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/ConfigPropsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function it_can_set_config_globally(bool $navigate)
$browser->visit('/props-from-config'.($navigate ? '?navigate=1' : ''))
->waitForText('Prop from Config')
->clickLink('Open')
->waitFor('.im-dialog')
->waitForModal()
->keys('', ['{escape}']) // Escape key does not close the dialog
->assertAttribute('#app', 'aria-hidden', 'true')
->clickLink('Open') // Clicking outside the dialog does not close it
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function it_passes_the_props_from_the_modal(bool $navigate)
$browser->visit('/props-from-modal'.($navigate ? '?navigate=1' : ''))
->waitForText('Prop from Modal')
->clickLink('Open Slideover')
->waitFor('.im-dialog')
->waitForModal()
->keys('', ['{escape}']) // Escape key does not close the dialog
->assertAttribute('#app', 'aria-hidden', 'true')
->clickLink('Open Slideover') // Clicking outside the dialog does not close it
Expand Down
6 changes: 3 additions & 3 deletions demo-app/tests/Browser/EmitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function it_can_dispatch_an_event_from_the_modal_to_the_visit_modal_metho
$browser->visit('/visit'.($navigate ? '?navigate=1' : ''))
->waitForText('Visit programmatically')
->press('Open Route Modal With Navigate')
->waitFor('.im-modal-content')
->waitForModal()
->clickLink('Send Message', 'button')
->assertDialogOpened('Hello from EditUser')
->dismissDialog();
Expand All @@ -49,9 +49,9 @@ public function it_can_dispatch_events_back_and_forth_between_nested_modals(bool
$browser->visit('/emit'.($navigate ? '?navigate=1' : ''))
->waitForText('Emit')
->clickLink('Open Modal')
->waitFor('.im-dialog')
->waitForModal()
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->waitForModal(1)
->clickLink('Push message to parent', 'button')
->waitForTextIn('@message', 'Hello from child')
->assertSeeIn('@greeting', 'Thanks from '.User::first()->name);
Expand Down
14 changes: 7 additions & 7 deletions demo-app/tests/Browser/EventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public function it_can_attach_listeners_to_the_modal_link(bool $navigate)
$browser->visit('/events'.($navigate ? '?navigate=1' : ''))
->waitForText('Events')
->clickLink('Open Modal')
->waitFor('.im-dialog')
->click('.im-close-button')
->waitUntilMissing('.im-dialog')
->waitForModal()
->clickModalCloseButton()
->waitUntilMissingModal()
->assertSeeIn('@log', 'start,success,close,after-leave');
});
}
Expand All @@ -31,12 +31,12 @@ public function it_can_attach_a_listener_for_blur(bool $navigate)
$browser->visit('/events'.($navigate ? '?navigate=1' : ''))
->waitForText('Events')
->clickLink('Open Modal')
->waitFor('.im-dialog')
->waitForModal()
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->waitForModal(1)
->assertSeeIn('@log', 'start,success,blur')
->click('.im-close-button')
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]')
->clickModalCloseButton(1)
->waitUntilMissingModal(1)
->assertSeeIn('@log', 'start,success,blur,focus');
});
}
Expand Down
4 changes: 2 additions & 2 deletions demo-app/tests/Browser/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function it_can_submit_a_form_from_within_the_modal_and_show_the_validati
->type('name', 'a')
->press('Save')
->waitForTextIn('.im-modal-content', 'The name field must be at least 3 characters.')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) {
->withinModal(function (Browser $browser) {
$browser->assertSee('The name field must be at least 3 characters.');
})
->assertMissing('.im-dialog[data-inertiaui-modal-index="1"]');
Expand All @@ -45,7 +45,7 @@ public function it_can_submit_a_form_and_redirect(bool $navigate)
->type('name', $newName = Str::random(10))
->press('Save')
->waitForText('User updated successfully!')
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertPathIs('/users');

$this->assertDatabaseHas('users', [
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/HeaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function it_can_open_a_modal_with_a_custom_header(bool $navigate)
$browser->visit('/header'.($navigate ? '?navigate=1' : ''))
->waitForText('Header')
->clickLink('Open Modal')
->waitFor('.im-dialog')
->waitForModal()
->assertSeeIn('@headerValue', 'Test Header Value');
});
}
Expand Down
10 changes: 5 additions & 5 deletions demo-app/tests/Browser/HistoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ public function it_can_open_a_modal_and_state_it_in_the_history()
$browser->visit('/users?navigate=1')
->waitForFirstUser()
->click("@edit-user-{$firstUser->id}")
->waitFor('.im-modal-content')
->waitForModal()
->assertSeeIn('.im-modal-content', 'Edit User')
->assertRouteIs('users.edit', ['user' => $firstUser->id])
->back()
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->waitForLocation('/users')
->assertQueryStringHas('navigate', '1')
->forward()
->waitFor('.im-modal-content')
->waitForModal()
->assertSeeIn('.im-modal-content', 'Edit User')
->assertRouteIs('users.edit', ['user' => $firstUser->id]);
});
Expand All @@ -46,7 +46,7 @@ public function it_can_redirect_back_to_the_same_base_route()
->type('name', $newName = Str::random(10))
->press('Save')
->waitForText('User updated successfully!')
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertPathIs('/users');

$this->assertDatabaseHas('users', [
Expand All @@ -70,7 +70,7 @@ public function it_can_redirect_back_to_a_different_base_route()
->type('name', $newName = Str::random(10))
->press('Save')
->waitForText('User updated successfully!')
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertPathIs('/users/'.$firstUser->id);

$this->assertDatabaseHas('users', [
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/LoadingPropTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function it_indicates_when_a_modal_is_loading(bool $navigate)
->waitForText('Loading Prop')
->clickLink('Open Slideover')
->assertSeeIn('@modal-link', 'Loading...')
->waitFor('.im-dialog')
->waitForModal()
->assertDontSeeIn('@modal-link', 'Loading...');
});
}
Expand Down
4 changes: 2 additions & 2 deletions demo-app/tests/Browser/LocalModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public function it_can_open_a_local_modal_and_a_nested_one()
->waitForTextIn('.im-modal-content', 'This is a local modal')
->clickLink('Create Role')
->waitForTextIn('.im-dialog[data-inertiaui-modal-index="1"]', 'Create Role')
->click('.im-close-button')
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]');
->clickModalCloseButton(1)
->waitUntilMissingModal(1);
});
}
}
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/MethodTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function it_can_open_a_modal_with_a_custom_method_and_data(bool $navigate
$browser->visit('/post-visit'.($navigate ? '?navigate=1' : ''))
->waitForText('POST Visit')
->clickLink('Open POST Modal')
->waitFor('.im-dialog')
->waitForModal()
->assertSeeIn('@message', 'Hey there!');
});
}
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/ModalLinkPropsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function it_passes_the_props_from_the_modal_link(bool $navigate)
$browser->visit('/props-from-modal-link'.($navigate ? '?navigate=1' : ''))
->waitForText('Prop from ModalLink')
->clickLink('Edit User 1')
->waitFor('.im-dialog')
->waitForModal()
->keys('', ['{escape}']) // Escape key does not close the dialog
->assertAttribute('#app', 'aria-hidden', 'true')
->clickLink('Edit User 1') // Clicking outside the dialog does not close it
Expand Down
14 changes: 7 additions & 7 deletions demo-app/tests/Browser/ModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public function it_can_open_the_modal_and_close_it_with_the_close_button()
$browser->visit('/users')
->waitForFirstUser()
->click("@edit-user-{$firstUser->id}")
->waitFor('.im-modal-content')
->waitForModal()
->assertSeeIn('.im-modal-content', 'Edit User')
->click('.im-close-button')
->waitUntilMissing('.im-dialog')
->clickModalCloseButton()
->waitUntilMissingModal()
->assertMissing('#headlessui-portal-root');
});
}
Expand All @@ -35,9 +35,9 @@ public function it_can_close_the_modal_by_clicking_outside_of_it()
->resize(1024, 768)
->waitForFirstUser()
->click("@edit-user-{$firstUser->id}")
->waitFor('.im-dialog')
->waitForModal()
->clickAt(100, 100)
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertMissing('#headlessui-portal-root');
});
}
Expand All @@ -52,9 +52,9 @@ public function it_can_close_the_modal_with_a_custom_button()
->resize(1024, 768)
->waitForFirstUser()
->click("@edit-user-{$firstUser->id}")
->waitFor('.im-dialog')
->waitForModal()
->press('Cancel')
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertMissing('#headlessui-portal-root');
});
}
Expand Down
26 changes: 13 additions & 13 deletions demo-app/tests/Browser/NestedModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ public function it_can_open_a_second_modal_on_top_of_the_first_one(bool $navigat
$browser->visit('/users?'.($navigate ? 'navigate=1' : ''))
->waitForFirstUser()
->click("@edit-user-{$firstUser->id}")
->waitFor('.im-dialog')
->waitForModal()
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->waitForModal(1)
->assertSeeIn('.im-dialog[data-inertiaui-modal-index="1"]', 'Create Role')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) {
->withinModal(function (Browser $browser) {
// The first modal should be blurred
$browser->assertAttributeContains('.im-modal-wrapper', 'class', 'blur-sm');
})
->click('.im-close-button')
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) {
->clickModalCloseButton(1)
->waitUntilMissingModal(1)
->withinModal(function (Browser $browser) {
// The first modal should not be blurred anymore
$browser->assertAttributeDoesntContain('.im-modal-wrapper', 'class', 'blur-sm');
})
->press('Save')
->waitUntilMissingText('Edit User')
->waitUntilMissing('.im-dialog');
->waitUntilMissingModal();
});
}

Expand All @@ -49,14 +49,14 @@ public function it_can_refresh_props_after_closing_the_second_modal()
$browser->visit('/users')
->waitForFirstUser()
->click('@edit-user-'.$browser->firstUser()->id)
->waitFor('.im-dialog')
->waitForModal()
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->within('.im-dialog[data-inertiaui-modal-index="1"]', function (Browser $browser) use ($newRoleName) {
->waitForModal(1)
->withinModal(function (Browser $browser) use ($newRoleName) {
$browser->type('name', $newRoleName)->press('Save');
})
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) use ($newRoleName) {
}, 1)
->waitUntilMissingModal(1)
->withinModal(function (Browser $browser) use ($newRoleName) {
$newRole = Role::where('name', $newRoleName)->firstOr(
fn () => $this->fail('New role was not saved.')
);
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/RedirectToModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function it_can_submit_a_form_and_redirect_back_to_the_same_modal()
->type('name', $newName = Str::random(10))
->press('Update and refresh')
->waitForText('User updated successfully!')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) use ($newName) {
->withinModal(function (Browser $browser) use ($newName) {
$browser->assertSee('Edit User '.$newName);
})
->assertPathIs('/users/'.$firstUser->id.'/edit');
Expand Down
2 changes: 1 addition & 1 deletion demo-app/tests/Browser/SessionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function it_can_submit_a_form_and_redirect_and_keep_the_user_logged_in(bo
->type('name', $newName = Str::random(10))
->press('Save')
->waitForText('User updated successfully!')
->waitUntilMissing('.im-dialog')
->waitUntilMissingModal()
->assertPathIs('/users')
->assertSee("Logged in as: {$firstUser->id}")
->assertAuthenticatedAs($firstUser);
Expand Down
12 changes: 6 additions & 6 deletions demo-app/tests/Browser/UseModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ public function it_can_inject_the_current_modal_context_from_a_component()
$this->browse(function (Browser $browser) {
$browser->visit('/users/1/edit')
->waitForFirstUser()
->waitFor('.im-dialog')
->within('.im-dialog[data-inertiaui-modal-index="0"]', function (Browser $browser) {
->waitForModal()
->withinModal(function (Browser $browser) {
$browser->assertSee('Close Modal with index 0');
})
->clickLink('Add Role')
->waitFor('.im-dialog[data-inertiaui-modal-index="1"]')
->within('.im-dialog[data-inertiaui-modal-index="1"]', function (Browser $browser) {
->waitForModal(1)
->withinModal(function (Browser $browser) {
$browser->assertSee('Close Modal with index 1');
})
}, 1)
->press('Close Modal with index 1')
->waitUntilMissing('.im-dialog[data-inertiaui-modal-index="1"]');
->waitUntilMissingModal(1);
});
}
}
10 changes: 5 additions & 5 deletions demo-app/tests/Browser/VisitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function it_can_programmatically_visit_a_local_modal(bool $navigate)
$browser->visit('/visit'.($navigate ? '?navigate=1' : ''))
->waitForText('Visit programmatically')
->press('Open Local Modal')
->waitFor('.im-modal-content')
->waitForModal()
->assertSeeIn('.im-modal-content', 'Hi there!');
});
}
Expand All @@ -31,7 +31,7 @@ public function it_can_programmatically_visit_a_modal(bool $navigate)
$browser->visit('/visit'.($navigate ? '?navigate=1' : ''))
->waitForText('Visit programmatically')
->press('Open Route Modal')
->waitFor('.im-modal-content')
->waitForModal()
->assertSeeIn('.im-modal-content', 'Hi again!');
});
}
Expand All @@ -44,10 +44,10 @@ public function it_can_programmatically_visit_a_modal_and_use_browser_navigation
$browser->visit('/visit')
->waitForText('Visit programmatically')
->press('Open Route Modal With Navigate')
->waitFor('.im-modal-content')
->waitForModal()
->assertPathIs('/users/1/edit')
->click('.im-close-button')
->waitUntilMissing('.im-dialog')
->clickModalCloseButton()
->waitUntilMissingModal()
->waitForLocation('/visit');
});
}
Expand Down
3 changes: 3 additions & 0 deletions demo-app/tests/DuskTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverDimension;
use Illuminate\Support\Collection;
use InertiaUI\Modal\Testing\DuskModalMacros;
use Laravel\Dusk\TestCase as BaseTestCase;
use PHPUnit\Framework\Attributes\AfterClass;
use PHPUnit\Framework\Attributes\BeforeClass;
Expand Down Expand Up @@ -176,6 +177,8 @@ protected function driver(): RemoteWebDriver
*/
protected function newBrowser($driver)
{
Browser::mixin(new DuskModalMacros);

return tap(new Browser($driver), function (Browser $browser) {
// Save the initial window size so we can restore it later.
static::$initialWindowSize ??= $browser->driver->manage()->window()->getSize();
Expand Down
Loading

0 comments on commit 059e1ca

Please sign in to comment.