Skip to content

Commit

Permalink
Add component() method to get scoped Browser instance (#1087)
Browse files Browse the repository at this point in the history
* tap component

* browser not component

* docs

* dont need proxy

* handle page

* tests

* resolver match

* fix cs

* test chaining
  • Loading branch information
ziadoz authored Feb 23, 2024
1 parent 5e038c4 commit dce7c4c
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 6 deletions.
21 changes: 21 additions & 0 deletions src/Browser.php
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,27 @@ public function elsewhereWhenAvailable($selector, Closure $callback, $seconds =
});
}

/**
* Return a browser scoped to the given component.
*
* @param \Laravel\Dusk\Component $component
* @return \Laravel\Dusk\Browser
*/
public function component(Component $component)
{
$browser = new static(
$this->driver, new ElementResolver($this->driver, $this->resolver->format($component))
);

if ($this->page) {
$browser->onWithoutAssert($this->page);
}

$browser->onComponent($component, $this->resolver);

return $browser;
}

/**
* Set the current component state.
*
Expand Down
137 changes: 131 additions & 6 deletions tests/Unit/ComponentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function test_within_method_triggers_assertion()
});
}

public function test_resolver_prefix()
public function test_within_method_resolver_prefix()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -48,7 +48,7 @@ public function test_resolver_prefix()
});
}

public function test_component_macros()
public function test_within_method_component_macros()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -64,7 +64,7 @@ public function test_component_macros()
});
}

public function test_component_elements()
public function test_within_method_component_elements()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -85,7 +85,7 @@ public function test_component_elements()
});
}

public function test_root_selector_can_be_dusk_hook()
public function test_within_method_root_selector_can_be_dusk_hook()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -98,7 +98,7 @@ public function test_root_selector_can_be_dusk_hook()
});
}

public function test_root_selector_can_be_element_alias()
public function test_within_method_root_selector_can_be_element_alias()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -111,7 +111,7 @@ public function test_root_selector_can_be_element_alias()
});
}

public function test_component_overrides_page_macros()
public function test_within_method_component_overrides_page_macros()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);
Expand All @@ -129,6 +129,131 @@ public function test_component_overrides_page_macros()
$this->assertTrue($browser->page->macroed);
});
}

public function test_within_method_chains()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$browser->within(new TestComponent, function ($browser) {
$this->assertInstanceOf(TestComponent::class, $browser->component);
$this->assertTrue($browser->component->asserted);
$this->assertSame('body #component-root', $browser->resolver->prefix);
$this->assertFalse($browser->component->macroed);

$browser->doSomething();
$this->assertTrue($browser->component->macroed);
})->within(new TestNestedComponent, function ($browser) {
$this->assertInstanceOf(TestNestedComponent::class, $browser->component);
$this->assertTrue($browser->component->asserted);
$this->assertSame('body #nested-root', $browser->resolver->prefix);
$this->assertFalse($browser->component->macroed);

$browser->doSomething();
$this->assertTrue($browser->component->macroed);
});
}

public function test_component_method_triggers_assertion()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$scoped = $browser->component(new TestComponent);
$this->assertTrue($scoped->component->asserted);

$nested = $scoped->component(new TestNestedComponent);
$this->assertTrue($nested->component->asserted);
}

public function test_component_method_resolver_prefix()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$scoped = $browser->component(new TestComponent);
$this->assertSame('body #component-root', $scoped->resolver->prefix);

$nested = $scoped->component(new TestNestedComponent);
$this->assertSame('body #component-root #nested-root', $nested->resolver->prefix);

$nested->with('prefix', function (Browser $browser) {
$this->assertSame('body #component-root #nested-root prefix', $browser->resolver->prefix);
});
}

public function test_component_method_component_macros()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$scoped = $browser->component(new TestComponent);
$scoped->doSomething();
$this->assertTrue($scoped->component->macroed);

$nested = $scoped->component(new TestNestedComponent);
$nested->doSomething();
$this->assertTrue($nested->component->macroed);
}

public function test_component_method_component_elements()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$scoped = $browser->component(new TestComponent);
$this->assertEquals([
'@component-alias' => '#component-alias',
'@overridden-alias' => '#not-overridden',
], $scoped->resolver->elements);

$nested = $scoped->component(new TestNestedComponent);
$this->assertEquals([
'@nested-alias' => '#nested-alias',
'@overridden-alias' => '#overridden',
'@component-alias' => '#component-alias',
], $nested->resolver->elements);
}

public function test_component_method_root_selector_can_be_dusk_hook()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$component = new TestComponent;
$component->selector = '@dusk-hook-root';

$scoped = $browser->component($component);
$this->assertSame('body [dusk="dusk-hook-root"]', $scoped->resolver->prefix);
}

public function test_component_method_root_selector_can_be_element_alias()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$component = new TestComponent;
$component->selector = '@component-alias';

$scoped = $browser->component($component);
$this->assertSame('body #component-alias', $scoped->resolver->prefix);
}

public function test_component_method_overrides_page_macros()
{
$driver = m::mock(stdClass::class);
$browser = new Browser($driver);

$browser->on($page = new TestPage);

$scoped = $browser->component(new TestComponent);
$scoped->doSomething();
$this->assertFalse($scoped->page->macroed);
$this->assertTrue($scoped->component->macroed);

$scoped->doPageSpecificThing();
$this->assertTrue($scoped->page->macroed);
}
}

class TestPage extends Page
Expand Down

0 comments on commit dce7c4c

Please sign in to comment.