diff --git a/README.md b/README.md index 9eec64c..66ba10d 100644 --- a/README.md +++ b/README.md @@ -157,8 +157,9 @@ $browser ->fillField('Name', 'Kevin') ->checkField('Accept Terms') ->uncheckField('Accept Terms') - ->selectFieldOption('Type', 'Employee') // single option select - ->selectFieldOptions('Notification', ['Email', 'SMS']) // multi-option select + ->selectField('Canada') // "radio" select + ->selectField('Type', 'Employee') // "select" single option + ->selectField('Notification', ['Email', 'SMS']) // "select" multiple options ->attachFile('Photo', '/path/to/photo.jpg') ->click('Submit') diff --git a/src/Browser.php b/src/Browser.php index 674bc71..dbeb76a 100644 --- a/src/Browser.php +++ b/src/Browser.php @@ -174,6 +174,14 @@ final public function fillField(string $selector, string $value): self */ final public function checkField(string $selector): self { + $field = $this->documentElement()->findField($selector); + + if ($field && 'radio' === \mb_strtolower($field->getAttribute('type'))) { + $this->documentElement()->selectFieldOption($selector, $field->getAttribute('value')); + + return $this; + } + $this->documentElement()->checkField($selector); return $this; @@ -189,6 +197,28 @@ final public function uncheckField(string $selector): self return $this; } + /** + * Select Radio, check checkbox, select single/multiple values. + * + * @param string|array|null $value null: check radio/checkbox + * string: single value + * array: multiple values + * + * @return static + */ + final public function selectField(string $selector, $value = null): self + { + if (\is_array($value)) { + return $this->selectFieldOptions($selector, $value); + } + + if (\is_string($value)) { + return $this->selectFieldOption($selector, $value); + } + + return $this->checkField($selector); + } + /** * @return static */ diff --git a/src/Browser/Mink/PantherDriver.php b/src/Browser/Mink/PantherDriver.php index 1488ea7..23e9021 100644 --- a/src/Browser/Mink/PantherDriver.php +++ b/src/Browser/Mink/PantherDriver.php @@ -171,6 +171,12 @@ public function attachFile($xpath, $path): void public function isChecked($xpath): bool { + $element = $this->crawlerElement($this->filteredCrawler($xpath)); + + if ('radio' === \mb_strtolower($element->getAttribute('type'))) { + return null !== $element->getAttribute('checked'); + } + return $this->choiceFormField($xpath)->hasValue(); } diff --git a/tests/BrowserTests.php b/tests/BrowserTests.php index 848c52c..bea2f55 100644 --- a/tests/BrowserTests.php +++ b/tests/BrowserTests.php @@ -296,6 +296,14 @@ public function form_assertions(): void ->assertNotSelected('Input 7', 'option 2') ->assertNotSelected('input7', 'option 2') ->assertNotSelected('input_7[]', 'option 2') + ->assertNotSelected('input_8', 'option 1') + ->assertSelected('input_8', 'option 2') + ->assertNotChecked('Radio 1') + ->assertNotChecked('radio1') + ->assertNotChecked('Radio 3') + ->assertNotChecked('radio3') + ->assertChecked('Radio 2') + ->assertChecked('radio2') ; } @@ -327,6 +335,7 @@ public function form_actions_by_field_label(): void ->selectFieldOption('Input 4', 'option 2') ->attachFile('Input 5', __FILE__) ->selectFieldOptions('Input 6', ['option 1', 'option 3']) + ->checkField('Radio 3') ->click('Submit') ->assertOn('/submit-form') ->assertContains('"input_1":"Kevin"') @@ -335,6 +344,7 @@ public function form_actions_by_field_label(): void ->assertContains('"input_4":"option 2"') ->assertContains(\sprintf('"input_5":"%s"', \pathinfo(__FILE__, \PATHINFO_BASENAME))) ->assertContains('"input_6":["option 1","option 3"]') + ->assertContains('"input_8":"option 3"') ; } @@ -351,6 +361,7 @@ public function form_actions_by_field_id(): void ->selectFieldOption('input4', 'option 2') ->attachFile('input5', __FILE__) ->selectFieldOptions('input6', ['option 1', 'option 3']) + ->checkField('radio3') ->click('Submit') ->assertOn('/submit-form') ->assertContains('"input_1":"Kevin"') @@ -359,6 +370,7 @@ public function form_actions_by_field_id(): void ->assertContains('"input_4":"option 2"') ->assertContains(\sprintf('"input_5":"%s"', \pathinfo(__FILE__, \PATHINFO_BASENAME))) ->assertContains('"input_6":["option 1","option 3"]') + ->assertContains('"input_8":"option 3"') ; } @@ -375,6 +387,7 @@ public function form_actions_by_field_name(): void ->selectFieldOption('input_4', 'option 2') ->attachFile('input_5', __FILE__) ->selectFieldOptions('input_6[]', ['option 1', 'option 3']) + ->selectFieldOption('input_8', 'option 3') ->click('Submit') ->assertOn('/submit-form') ->assertContains('"input_1":"Kevin"') @@ -383,6 +396,27 @@ public function form_actions_by_field_name(): void ->assertContains('"input_4":"option 2"') ->assertContains(\sprintf('"input_5":"%s"', \pathinfo(__FILE__, \PATHINFO_BASENAME))) ->assertContains('"input_6":["option 1","option 3"]') + ->assertContains('"input_8":"option 3"') + ; + } + + /** + * @test + */ + public function select_field(): void + { + $this->browser() + ->visit('/page1') + ->selectField('Input 2') + ->selectField('Input 4', 'option 2') + ->selectField('Input 6', ['option 1', 'option 3']) + ->selectField('Radio 3') + ->click('Submit') + ->assertOn('/submit-form') + ->assertContains('"input_2":"on"') + ->assertContains('"input_4":"option 2"') + ->assertContains('"input_6":["option 1","option 3"]') + ->assertContains('"input_8":"option 3"') ; } diff --git a/tests/Fixture/Kernel.php b/tests/Fixture/Kernel.php index bf2c4f0..15ee9e3 100644 --- a/tests/Fixture/Kernel.php +++ b/tests/Fixture/Kernel.php @@ -54,7 +54,7 @@ public function submitForm(Request $request): JsonResponse { return new JsonResponse(\array_merge( $request->request->all(), - \array_map(fn(UploadedFile $file) => $file->getClientOriginalName(), $request->files->all()) + \array_map(fn(UploadedFile $file) => $file->getClientOriginalName(), \array_filter($request->files->all())) )); } diff --git a/tests/Fixture/files/page1.html b/tests/Fixture/files/page1.html index 2b7c703..088c674 100644 --- a/tests/Fixture/files/page1.html +++ b/tests/Fixture/files/page1.html @@ -45,6 +45,13 @@