diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/FillFormAction.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/FillFormAction.java new file mode 100644 index 0000000000..e6987422f5 --- /dev/null +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/FillFormAction.java @@ -0,0 +1,124 @@ +/* + * Copyright 2006-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.selenium.actions; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.citrusframework.context.TestContext; +import org.citrusframework.selenium.endpoint.SeleniumBrowser; +import org.openqa.selenium.By; +import org.openqa.selenium.json.Json; + +/** + * Fill out form with given key-value pairs where each key is used to find the form field. + * Sets field values with set input action that supports both input and select form controls. + * Supports to submit the form after all fields are set. + * + * @author Christoph Deppisch + */ +public class FillFormAction extends AbstractSeleniumAction { + + /** Key value pairs representing the form fields to fill */ + private final Map formFields; + + /** Optional submit button id that gets clicked after fields are filled */ + private final By submitButton; + + /** + * Default constructor. + */ + public FillFormAction(Builder builder) { + super("fill-form", builder); + + this.formFields = builder.formFields; + this.submitButton = builder.submitButton; + } + + @Override + public void execute(SeleniumBrowser browser, TestContext context) { + formFields.forEach((by, value) -> { + new SetInputAction.Builder() + .element(by) + .value(value) + .build() + .execute(browser, context); + }); + + if (submitButton != null) { + new ClickAction.Builder() + .element(submitButton) + .build() + .execute(browser, context); + } + } + + public Map getFormFields() { + return formFields; + } + + public By getSubmitButton() { + return submitButton; + } + + /** + * Action builder. + */ + public static class Builder extends AbstractSeleniumAction.Builder { + + private final Map formFields = new LinkedHashMap<>(); + + private By submitButton; + + public Builder field(By by, String value) { + this.formFields.put(by, value); + return this; + } + + public Builder field(String id, String value) { + return field(By.id(id), value); + } + + public Builder fromJson(String formFieldsJson) { + return fields(new Json().toType(formFieldsJson, Map.class)); + } + + public Builder submit() { + this.submitButton = By.xpath("//input[@type='submit']"); + return this; + } + + public Builder submit(String id) { + return submit(By.id(id)); + } + + public Builder submit(By button) { + this.submitButton = button; + return this; + } + + public Builder fields(Map fields) { + fields.forEach(this::field); + return this; + } + + @Override + public FillFormAction build() { + return new FillFormAction(this); + } + } +} diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SeleniumActionBuilder.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SeleniumActionBuilder.java index bbd4d70f9f..b8b23f590c 100644 --- a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SeleniumActionBuilder.java +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SeleniumActionBuilder.java @@ -204,6 +204,16 @@ public SetInputAction.Builder setInput() { return builder; } + /** + * Fill form action. + */ + public FillFormAction.Builder fillForm() { + FillFormAction.Builder builder = new FillFormAction.Builder() + .browser(seleniumBrowser); + this.delegate = builder; + return builder; + } + /** * Check input action. */ diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SetInputAction.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SetInputAction.java index 97890e2557..f9b8744605 100644 --- a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SetInputAction.java +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/actions/SetInputAction.java @@ -46,7 +46,7 @@ protected void execute(WebElement webElement, SeleniumBrowser browser, TestConte super.execute(webElement, browser, context); String tagName = webElement.getTagName(); - if (null == tagName || !"select".equals(tagName.toLowerCase())) { + if (!"select".equalsIgnoreCase(tagName)) { webElement.clear(); webElement.sendKeys(context.replaceDynamicContentInString(value)); } else { diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/FillForm.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/FillForm.java new file mode 100644 index 0000000000..ddcc61390e --- /dev/null +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/FillForm.java @@ -0,0 +1,142 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.selenium.xml; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.XmlType; +import org.citrusframework.TestActor; +import org.citrusframework.selenium.actions.AbstractSeleniumAction; +import org.citrusframework.selenium.actions.FillFormAction; +import org.citrusframework.selenium.endpoint.SeleniumBrowser; + +@XmlRootElement(name = "fill-form") +public class FillForm extends AbstractSeleniumAction.Builder { + + private final FillFormAction.Builder delegate = new FillFormAction.Builder(); + + @XmlElement(name = "fields") + public void setFields(Fields fields) { + delegate.fields(fields.getFields() + .stream() + .collect(Collectors.toMap(Fields.Field::getId, Fields.Field::getValue))); + } + + @XmlElement(name = "json") + public void setJson(String json) { + this.delegate.fromJson(json); + } + + @XmlAttribute + public void setSubmit(String value) { + this.delegate.submit(value); + } + + @Override + public FillForm description(String description) { + delegate.description(description); + return this; + } + + @Override + public FillForm actor(TestActor actor) { + delegate.actor(actor); + return this; + } + + @Override + public FillForm browser(SeleniumBrowser seleniumBrowser) { + delegate.browser(seleniumBrowser); + return this; + } + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "fields" + }) + public static class Fields { + @XmlElement(name = "field") + private List fields; + + public void setFields(List fields) { + this.fields = fields; + } + + public List getFields() { + if (fields == null) { + fields = new ArrayList<>(); + } + + return fields; + } + + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = {}) + public static class Field { + @XmlAttribute + private String id; + @XmlAttribute + private String value; + + @XmlElement(name = "value") + private String valueData; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValue() { + if (value == null) { + return getValueData(); + } + + return value; + } + + public String getValueData() { + return valueData; + } + + public void setValueData(String valueData) { + this.valueData = valueData; + } + } + } + + @Override + public FillFormAction build() { + return delegate.build(); + } +} diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/Selenium.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/Selenium.java index fccf930b58..8a3332220f 100644 --- a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/Selenium.java +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/xml/Selenium.java @@ -130,6 +130,14 @@ public void setSetInput(SetInput builder) { this.builder = builder; } + /** + * Fill form action. + */ + @XmlElement(name = "fill-form") + public void setFillForm(FillForm builder) { + this.builder = builder; + } + /** * Check input action. */ diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/FillForm.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/FillForm.java new file mode 100644 index 0000000000..5d62a3aa65 --- /dev/null +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/FillForm.java @@ -0,0 +1,91 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.selenium.yaml; + +import java.util.List; +import java.util.stream.Collectors; + +import org.citrusframework.TestActor; +import org.citrusframework.selenium.actions.AbstractSeleniumAction; +import org.citrusframework.selenium.actions.FillFormAction; +import org.citrusframework.selenium.endpoint.SeleniumBrowser; + +public class FillForm extends AbstractSeleniumAction.Builder { + + private final FillFormAction.Builder delegate = new FillFormAction.Builder(); + + public void setFields(List fields) { + delegate.fields(fields + .stream() + .collect(Collectors.toMap(Field::getId, Field::getValue))); + } + + public void setJson(String json) { + this.delegate.fromJson(json); + } + + public void setSubmit(String value) { + this.delegate.submit(value); + } + + @Override + public FillForm description(String description) { + delegate.description(description); + return this; + } + + @Override + public FillForm actor(TestActor actor) { + delegate.actor(actor); + return this; + } + + @Override + public FillForm browser(SeleniumBrowser seleniumBrowser) { + delegate.browser(seleniumBrowser); + return this; + } + + public static class Field { + private String id; + private String value; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + @Override + public FillFormAction build() { + return delegate.build(); + } +} diff --git a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/Selenium.java b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/Selenium.java index 98898f883a..0ca381d15d 100644 --- a/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/Selenium.java +++ b/connectors/citrus-selenium/src/main/java/org/citrusframework/selenium/yaml/Selenium.java @@ -114,6 +114,13 @@ public void setSetInput(SetInput builder) { this.builder = builder; } + /** + * Fill form action. + */ + public void setFillForm(FillForm builder) { + this.builder = builder; + } + /** * Check input action. */ diff --git a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/actions/FillFormActionTest.java b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/actions/FillFormActionTest.java new file mode 100644 index 0000000000..695ccb2e3d --- /dev/null +++ b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/actions/FillFormActionTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2006-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.selenium.actions; + +import java.util.Collections; + +import org.citrusframework.selenium.endpoint.SeleniumBrowser; +import org.citrusframework.testng.AbstractTestNGUnitTest; +import org.mockito.Mockito; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.mockito.Mockito.*; + +/** + * @author Christoph Deppisch + */ +public class FillFormActionTest extends AbstractTestNGUnitTest { + + private final SeleniumBrowser seleniumBrowser = new SeleniumBrowser(); + private final WebDriver webDriver = Mockito.mock(WebDriver.class); + private final WebElement element = Mockito.mock(WebElement.class); + + @BeforeMethod + public void setup() { + reset(webDriver, element); + + seleniumBrowser.setWebDriver(webDriver); + + when(element.isDisplayed()).thenReturn(true); + when(element.isEnabled()).thenReturn(true); + when(element.getTagName()).thenReturn("input"); + } + + @Test + public void testExecute() throws Exception { + when(webDriver.findElement(any(By.class))).thenReturn(element); + + FillFormAction action = new FillFormAction.Builder() + .browser(seleniumBrowser) + .field("username", "foo_user") + .field("password", "secret") + .build(); + action.execute(context); + + verify(element, times(2)).clear(); + verify(element).sendKeys("foo_user"); + verify(element).sendKeys("secret"); + } + + @Test + public void testExecuteWithSelect() throws Exception { + WebElement option = Mockito.mock(WebElement.class); + + when(webDriver.findElement(any(By.class))).thenReturn(element); + when(element.getTagName()).thenReturn("select"); + + when(element.findElements(any(By.class))).thenReturn(Collections.singletonList(option)); + when(option.isEnabled()).thenReturn(true); + when(option.isSelected()).thenReturn(false); + + FillFormAction action = new FillFormAction.Builder() + .browser(seleniumBrowser) + .field("remember-me", "yes") + .build(); + action.execute(context); + + verify(option).click(); + } + + @Test + public void testExecuteWithJson() throws Exception { + when(webDriver.findElement(any(By.class))).thenReturn(element); + + FillFormAction action = new FillFormAction.Builder() + .browser(seleniumBrowser) + .fromJson(""" + { + "username": "foo_user", + "password": "secret" + } + """) + .build(); + action.execute(context); + + verify(element, times(2)).clear(); + verify(element).sendKeys("foo_user"); + verify(element).sendKeys("secret"); + } + + @Test + public void testExecuteWithFormSubmit() throws Exception { + when(webDriver.findElement(any(By.class))).thenReturn(element); + + FillFormAction action = new FillFormAction.Builder() + .browser(seleniumBrowser) + .field("username", "foo_user") + .field("password", "secret") + .submit("save") + .build(); + action.execute(context); + + verify(element, times(2)).clear(); + verify(element).sendKeys("foo_user"); + verify(element).sendKeys("secret"); + verify(element).click(); + } + +} diff --git a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/groovy/SeleniumTest.java b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/groovy/SeleniumTest.java index fdd8edefd7..a06941c60d 100644 --- a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/groovy/SeleniumTest.java +++ b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/groovy/SeleniumTest.java @@ -132,7 +132,7 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertEquals(result.getName(), "SeleniumTest"); Assert.assertEquals(result.getMetaInfo().getAuthor(), "Christoph"); Assert.assertEquals(result.getMetaInfo().getStatus(), TestCaseMetaInfo.Status.FINAL); - Assert.assertEquals(result.getActionCount(), 23L); + Assert.assertEquals(result.getActionCount(), 25L); int actionIndex = 0; @@ -220,6 +220,23 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertNull(dropDownMultiSelect.getOption()); Assert.assertEquals(dropDownMultiSelect.getOptions().size(), 2L); + FillFormAction fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + + fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNotNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getSubmitButton(), By.id("save")); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + WaitUntilAction waitUntilAction = (WaitUntilAction) result.getTestAction(actionIndex++); Assert.assertNull(waitUntilAction.getBrowser()); Assert.assertEquals(waitUntilAction.getName(), "selenium:wait"); diff --git a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/xml/SeleniumTest.java b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/xml/SeleniumTest.java index abd0180f19..d6f14e3736 100644 --- a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/xml/SeleniumTest.java +++ b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/xml/SeleniumTest.java @@ -133,7 +133,7 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertEquals(result.getName(), "SeleniumTest"); Assert.assertEquals(result.getMetaInfo().getAuthor(), "Christoph"); Assert.assertEquals(result.getMetaInfo().getStatus(), TestCaseMetaInfo.Status.FINAL); - Assert.assertEquals(result.getActionCount(), 23L); + Assert.assertEquals(result.getActionCount(), 25L); int actionIndex = 0; @@ -221,6 +221,23 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertNull(dropDownMultiSelect.getOption()); Assert.assertEquals(dropDownMultiSelect.getOptions().size(), 2L); + FillFormAction fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + + fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNotNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getSubmitButton(), By.id("save")); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + WaitUntilAction waitUntilAction = (WaitUntilAction) result.getTestAction(actionIndex++); Assert.assertNull(waitUntilAction.getBrowser()); Assert.assertEquals(waitUntilAction.getName(), "selenium:wait"); diff --git a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/yaml/SeleniumTest.java b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/yaml/SeleniumTest.java index 8bf9302db6..6992602bc8 100644 --- a/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/yaml/SeleniumTest.java +++ b/connectors/citrus-selenium/src/test/java/org/citrusframework/selenium/yaml/SeleniumTest.java @@ -133,7 +133,7 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertEquals(result.getName(), "SeleniumTest"); Assert.assertEquals(result.getMetaInfo().getAuthor(), "Christoph"); Assert.assertEquals(result.getMetaInfo().getStatus(), TestCaseMetaInfo.Status.FINAL); - Assert.assertEquals(result.getActionCount(), 23L); + Assert.assertEquals(result.getActionCount(), 25L); int actionIndex = 0; @@ -221,6 +221,23 @@ public void shouldLoadSeleniumActions() throws IOException { Assert.assertNull(dropDownMultiSelect.getOption()); Assert.assertEquals(dropDownMultiSelect.getOptions().size(), 2L); + FillFormAction fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + + fillForm = (FillFormAction) result.getTestAction(actionIndex++); + Assert.assertNull(fillForm.getBrowser()); + Assert.assertEquals(fillForm.getName(), "selenium:fill-form"); + Assert.assertNotNull(fillForm.getSubmitButton()); + Assert.assertEquals(fillForm.getSubmitButton(), By.id("save")); + Assert.assertEquals(fillForm.getFormFields().size(), 2L); + Assert.assertEquals(fillForm.getFormFields().get(By.id("username")), "foo_user"); + Assert.assertEquals(fillForm.getFormFields().get(By.id("password")), "secret"); + WaitUntilAction waitUntilAction = (WaitUntilAction) result.getTestAction(actionIndex++); Assert.assertNull(waitUntilAction.getBrowser()); Assert.assertEquals(waitUntilAction.getName(), "selenium:wait"); diff --git a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/groovy/selenium.test.groovy b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/groovy/selenium.test.groovy index cdf056eeeb..32a8acd012 100644 --- a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/groovy/selenium.test.groovy +++ b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/groovy/selenium.test.groovy @@ -102,6 +102,23 @@ actions { .options("Mr.", "Dr.") ) + $(selenium() + .fillForm() + .field("username", "foo_user") + .field("password", "secret") + ) + + $(selenium() + .fillForm() + .fromJson(""" + { + "username": "foo_user", + "password": "secret" + } + """) + .submit(By.id("save")) + ) + $(selenium() .waitUntil() .hidden() diff --git a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/xml/selenium-test.xml b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/xml/selenium-test.xml index a2a7c4f0df..c9083f64ad 100644 --- a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/xml/selenium-test.xml +++ b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/xml/selenium-test.xml @@ -104,6 +104,28 @@ + + + + + + secret + + + + + + + + + { + "username": "foo_user", + "password": "secret" + } + + + + diff --git a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/yaml/selenium-test.yaml b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/yaml/selenium-test.yaml index c0af977daa..b9d13d221f 100644 --- a/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/yaml/selenium-test.yaml +++ b/connectors/citrus-selenium/src/test/resources/org/citrusframework/selenium/yaml/selenium-test.yaml @@ -79,6 +79,20 @@ actions: - "Mr." - "Dr." + - selenium: + fill-form: + fields: + - id: "username" + value: "foo_user" + - id: "password" + value: "secret" + + - selenium: + fill-form: + submit: "save" + json: | + { "username": "foo_user", "password": "secret" } + - selenium: wait-until: condition: "hidden" diff --git a/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase-4.1.0-SNAPSHOT.xsd b/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase-4.1.0-SNAPSHOT.xsd index e2b5d92697..a60629928a 100644 --- a/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase-4.1.0-SNAPSHOT.xsd +++ b/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase-4.1.0-SNAPSHOT.xsd @@ -1313,6 +1313,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase.xsd b/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase.xsd index e2b5d92697..a60629928a 100644 --- a/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase.xsd +++ b/runtime/citrus-xml/src/main/resources/org/citrusframework/schema/xml/testcase/citrus-testcase.xsd @@ -1313,6 +1313,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/manual/endpoint-selenium.adoc b/src/manual/endpoint-selenium.adoc index 001ecdb10d..ccfe2541e0 100644 --- a/src/manual/endpoint-selenium.adoc +++ b/src/manual/endpoint-selenium.adoc @@ -158,6 +158,7 @@ selenium:navigate:: Navigates to new page url (including history back, forward a selenium:set-input:: Finds input element and sets value selenium:check-input:: Finds checkbox element and sets/unsets value selenium:dropdown-select:: Finds dropdown element and selects single or multiple value/s +selenium:fill-form:: Fills form with given values and optionally submits form afterwards. Supports setting multiple fields at the same time. selenium:page:: Instantiate page object with dependency injection and execute page action with verification selenium:open:: Open new window selenium:close:: Close window by given name @@ -358,6 +359,63 @@ selenium().select("happy").element(By.id("user-mood")); The actions above select dropdown options and set user input on text fields and checkboxes. As usual the form elements are selected by some properties such as ids, names or xpath expressions. +[[form-fill-actions]] +== Fill form + +The fill form action sets multiple form fields with given values and optionally submits the form afterwards. + +.XML DSL +[source,xml] +---- + + + + + + +---- + +.Java DSL +[source,java] +---- +selenium().fillForm() + .field("username", "foo_user") + .field("password", "${secret}") + .submit("save"); +---- + +The actions above set the form fields identified by its id and sets the given values. The actions supports input fields, checkboxes and drop-down select controls. Optionally the form gets submitted by clicking on the given submit button once all fields are set. + +The user also has the opportunity to set the form fields via Json object where each property in the Json object represents a form field. + +.XML DSL +[source,xml] +---- + + + { + "username": "foo_user", + "password": "secret" + } + + +---- + +.Java DSL +[source,java] +---- +selenium().fillForm() + .fromJson(""" + { + "username": "foo_user", + "password": "secret" + } + """) + .submit(By.id("save"); +---- + +This will set the form fields `username` and `password` with the given values before submitting the form. + [[page-actions]] == Page actions