From 5e7fabb9d2f634c720f848175545f02dd0a480f1 Mon Sep 17 00:00:00 2001 From: Jasper de Vries Date: Fri, 29 Dec 2023 16:31:02 +0100 Subject: [PATCH] Add IT for loading state --- .../commandbutton/CommandButton001.java | 46 +++++++++++ .../commandbutton/commandButton001.xhtml | 23 ++++++ .../commandbutton/CommandButton001Test.java | 79 +++++++++++++++++++ .../selenium/AbstractPrimePageTest.java | 9 ++- .../resources/primefaces/core/core.js | 4 +- .../primefaces/forms/forms.commandlink.js | 5 +- 6 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 primefaces-integration-tests/src/main/java/org/primefaces/integrationtests/commandbutton/CommandButton001.java create mode 100644 primefaces-integration-tests/src/main/webapp/commandbutton/commandButton001.xhtml create mode 100644 primefaces-integration-tests/src/test/java/org/primefaces/integrationtests/commandbutton/CommandButton001Test.java diff --git a/primefaces-integration-tests/src/main/java/org/primefaces/integrationtests/commandbutton/CommandButton001.java b/primefaces-integration-tests/src/main/java/org/primefaces/integrationtests/commandbutton/CommandButton001.java new file mode 100644 index 0000000000..807307671c --- /dev/null +++ b/primefaces-integration-tests/src/main/java/org/primefaces/integrationtests/commandbutton/CommandButton001.java @@ -0,0 +1,46 @@ +/* + * The MIT License + * + * Copyright (c) 2009-2023 PrimeTek Informatics + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.primefaces.integrationtests.commandbutton; + +import java.io.Serializable; + +import javax.faces.view.ViewScoped; +import javax.inject.Named; + +import org.primefaces.integrationtests.general.utilities.TestUtils; + +import lombok.Data; + +@Named +@ViewScoped +@Data +public class CommandButton001 implements Serializable { + + private static final long serialVersionUID = 1L; + + public void submit() { + TestUtils.addMessage("Submit"); + } + +} diff --git a/primefaces-integration-tests/src/main/webapp/commandbutton/commandButton001.xhtml b/primefaces-integration-tests/src/main/webapp/commandbutton/commandButton001.xhtml new file mode 100644 index 0000000000..569279d080 --- /dev/null +++ b/primefaces-integration-tests/src/main/webapp/commandbutton/commandButton001.xhtml @@ -0,0 +1,23 @@ + + + + + + + + + + Hello + + + + + + + + \ No newline at end of file diff --git a/primefaces-integration-tests/src/test/java/org/primefaces/integrationtests/commandbutton/CommandButton001Test.java b/primefaces-integration-tests/src/test/java/org/primefaces/integrationtests/commandbutton/CommandButton001Test.java new file mode 100644 index 0000000000..e0aa6765c1 --- /dev/null +++ b/primefaces-integration-tests/src/test/java/org/primefaces/integrationtests/commandbutton/CommandButton001Test.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * + * Copyright (c) 2009-2023 PrimeTek Informatics + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.primefaces.integrationtests.commandbutton; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.support.FindBy; +import org.primefaces.selenium.AbstractPrimePage; +import org.primefaces.selenium.AbstractPrimePageTest; +import org.primefaces.selenium.PrimeSelenium; +import org.primefaces.selenium.component.CommandButton; + +public class CommandButton001Test extends AbstractPrimePageTest { + + @Test + @Order(1) + @DisplayName("CommandButton: loading state") + void loadingState(Page page) { + // Arrange + CommandButton button = page.button; + setMinLoadAnim(100); + + // Act + page.button.click(); + + // Assert + assertTrue(PrimeSelenium.hasCssClass(button, "ui-state-loading")); + } + + @Test + @Order(2) + @DisplayName("CommandButton: loading state 2") + void loadingState2(Page page) { + // Arrange + CommandButton button = page.button; + noMinLoadAnim(); + + // Act + page.button.click(); + + // Assert + assertFalse(PrimeSelenium.hasCssClass(button, "ui-state-loading")); + } + + public static class Page extends AbstractPrimePage { + @FindBy(id = "form:button") + CommandButton button; + + @Override + public String getLocation() { + return "commandbutton/commandButton001.xhtml"; + } + } + +} diff --git a/primefaces-selenium/primefaces-selenium-core/src/main/java/org/primefaces/selenium/AbstractPrimePageTest.java b/primefaces-selenium/primefaces-selenium-core/src/main/java/org/primefaces/selenium/AbstractPrimePageTest.java index 7a5bbeff57..9b0f7825ba 100644 --- a/primefaces-selenium/primefaces-selenium-core/src/main/java/org/primefaces/selenium/AbstractPrimePageTest.java +++ b/primefaces-selenium/primefaces-selenium-core/src/main/java/org/primefaces/selenium/AbstractPrimePageTest.java @@ -315,7 +315,14 @@ protected void assertCss(WebElement element, String... cssClasses) { } protected void noMinLoadAnim() { - PrimeSelenium.executeScript("PrimeFaces.ajax.minLoadAnim = 0;"); + setMinLoadAnim(0); + } + + protected void setMinLoadAnim(int milliseconds) { + if (milliseconds < 0) { + throw new IllegalArgumentException("milliseconds cannot be negative"); + } + PrimeSelenium.executeScript("PrimeFaces.ajax.minLoadAnim = " + milliseconds + ";"); } /** diff --git a/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js b/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js index f702aa0164..1d447e45c4 100644 --- a/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js +++ b/primefaces/src/main/resources/META-INF/resources/primefaces/core/core.js @@ -400,7 +400,7 @@ } button.addClass('ui-state-loading'); - button.data('ajaxstart', Date.now()); + widget.ajaxStart = Date.now(); if (typeof widget.disable === 'function' && widget.cfg.disableOnAjax !== false) { @@ -424,7 +424,7 @@ PrimeFaces.queueTask( function(){ PrimeFaces.buttonEndAjaxDisabled(widget, button); }, - Math.max(PrimeFaces.ajax.minLoadAnim + button.data('ajaxstart') - Date.now(), 0) + Math.max(PrimeFaces.ajax.minLoadAnim + widget.ajaxStart - Date.now(), 0) ); } }); diff --git a/primefaces/src/main/resources/META-INF/resources/primefaces/forms/forms.commandlink.js b/primefaces/src/main/resources/META-INF/resources/primefaces/forms/forms.commandlink.js index c561428970..21546cf3f3 100644 --- a/primefaces/src/main/resources/META-INF/resources/primefaces/forms/forms.commandlink.js +++ b/primefaces/src/main/resources/META-INF/resources/primefaces/forms/forms.commandlink.js @@ -4,6 +4,7 @@ * CommandLink is an extended version of standard commandLink with AJAX and theming. * * @prop {number} [ajaxCount] Number of concurrent active Ajax requests. + * @prop {number} [ajaxCount] Timestamp of the Ajax request that started the animation. * * @interface {PrimeFaces.widget.CommandLinkCfg} cfg The configuration for the {@link CommandLink| CommandLink widget}. * You can access this configuration via {@link PrimeFaces.widget.BaseWidget.cfg|BaseWidget.cfg}. Please note that this @@ -56,7 +57,7 @@ PrimeFaces.widget.CommandLink = PrimeFaces.widget.BaseWidget.extend({ } if (PrimeFaces.ajax.Utils.isXhrSource($this, settings)) { $this.jq.addClass('ui-state-loading'); - $this.jq.data('ajaxstart', Date.now()); + $this.ajaxStart = Date.now(); $this.disable(); } }).on('pfAjaxComplete.' + this.id, function(e, xhr, settings, args) { @@ -67,7 +68,7 @@ PrimeFaces.widget.CommandLink = PrimeFaces.widget.BaseWidget.extend({ if (PrimeFaces.ajax.Utils.isXhrSource($this, settings)) { PrimeFaces.queueTask( function(){ $this.endAjaxDisabled($this); }, - Math.max(PrimeFaces.ajax.minLoadAnim + $this.jq.data('ajaxstart') - Date.now(), 0) + Math.max(PrimeFaces.ajax.minLoadAnim + $this.ajaxStart - Date.now(), 0) ); } });