diff --git a/test/src/test/java/org/kohsuke/stapler/beanutils/TagTest.java b/test/src/test/java/org/kohsuke/stapler/beanutils/TagTest.java
new file mode 100644
index 0000000000..314efefd11
--- /dev/null
+++ b/test/src/test/java/org/kohsuke/stapler/beanutils/TagTest.java
@@ -0,0 +1,130 @@
+package org.kohsuke.stapler.beanutils;
+
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import hudson.model.InvisibleAction;
+import hudson.model.RootAction;
+import org.hamcrest.MatcherAssert;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.TestExtension;
+import org.kohsuke.stapler.jelly.StaplerTagLibrary;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class TagTest {
+ public static final String ROOT_ACTION_URL = "tagtest";
+ @Rule
+ public JenkinsRule j = new JenkinsRule();
+
+ @Test
+ public void testTagLib() throws Exception {
+ final JenkinsRule.WebClient wc = j.createWebClient().withThrowExceptionOnFailingStatusCode(false);
+ { // Jelly views with basic include variants
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeIt");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeClass");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeClassByName");
+ assertThat(page.getWebResponse().getStatusCode(), is(500));
+ }
+ }
+ { // Groovy views
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibWithClassInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibWithItInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceWithClassInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceWithItInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ }
+ try {
+ StaplerTagLibrary.DISABLE_INCLUDE_TAG_CLASS_ATTRIBUTE_REWRITING = true;
+
+ { // Jelly views with basic include variants
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeIt");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeClass");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/jellyStIncludeClassByName");
+ assertThat(page.getWebResponse().getStatusCode(), is(500));
+ }
+ }
+ { // Groovy views
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibWithClassInclude");
+ assertThat(page.getWebResponse().getStatusCode(), is(500));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyLibWithItInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceWithClassInclude");
+ assertThat(page.getWebResponse().getStatusCode(), is(500));
+ }
+ {
+ final HtmlPage page = wc.goTo(ROOT_ACTION_URL + "/groovyNamespaceWithItInclude");
+ assertThat(page.getWebResponse().getContentAsString(), containsString("Hello, World"));
+ }
+ }
+ } finally {
+ StaplerTagLibrary.DISABLE_INCLUDE_TAG_CLASS_ATTRIBUTE_REWRITING = false;
+ }
+ }
+
+ @TestExtension
+ public static class RootActionImpl extends InvisibleAction implements RootAction {
+ @Override
+ public String getUrlName() {
+ return ROOT_ACTION_URL;
+ }
+ }
+
+}
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/_included.jelly b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/_included.jelly
new file mode 100644
index 0000000000..4cd62819ab
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/_included.jelly
@@ -0,0 +1,4 @@
+
+
+ Hello, World!
+
\ No newline at end of file
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibInclude.groovy
new file mode 100644
index 0000000000..357938bf76
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibInclude.groovy
@@ -0,0 +1,8 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+import org.kohsuke.stapler.jelly.StaplerTagLibrary
+
+def lib = jelly(StaplerTagLibrary.class)
+
+lib.contentType(value: "text/html")
+lib.include(page: "_included")
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithClassInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithClassInclude.groovy
new file mode 100644
index 0000000000..7e4a60a98d
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithClassInclude.groovy
@@ -0,0 +1,10 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+import org.kohsuke.stapler.jelly.StaplerTagLibrary
+
+def lib = jelly(StaplerTagLibrary.class)
+
+lib.contentType(value: "text/html")
+
+// This case would fail without the compatibility code: 'class' attribute set in a Groovy view
+lib.include(page: "_included", class: it.class)
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithItInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithItInclude.groovy
new file mode 100644
index 0000000000..ff94d459ce
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyLibWithItInclude.groovy
@@ -0,0 +1,8 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+import org.kohsuke.stapler.jelly.StaplerTagLibrary
+
+def lib = jelly(StaplerTagLibrary.class)
+
+lib.contentType(value: "text/html")
+lib.include(page: "_included", it: my)
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceInclude.groovy
new file mode 100644
index 0000000000..5ad2cef2de
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceInclude.groovy
@@ -0,0 +1,6 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+def st = namespace("jelly:stapler")
+
+st.contentType(value: "text/html")
+st.include(page: "_included")
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithClassInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithClassInclude.groovy
new file mode 100644
index 0000000000..ce447c550b
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithClassInclude.groovy
@@ -0,0 +1,8 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+def st = namespace("jelly:stapler")
+
+st.contentType(value: "text/html")
+
+// This case would fail without the compatibility code: 'class' attribute set in a Groovy view
+st.include(page: "_included", class: it.class)
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithItInclude.groovy b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithItInclude.groovy
new file mode 100644
index 0000000000..9950bbc701
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/groovyNamespaceWithItInclude.groovy
@@ -0,0 +1,6 @@
+package org.kohsuke.stapler.beanutils.TagTest.RootActionImpl
+
+def st = namespace("jelly:stapler")
+
+st.contentType(value: "text/html")
+st.include(page: "_included", it: my)
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStInclude.jelly b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStInclude.jelly
new file mode 100644
index 0000000000..74e0a6d5c9
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStInclude.jelly
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClass.jelly b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClass.jelly
new file mode 100644
index 0000000000..4dc378ac21
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClass.jelly
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClassByName.jelly b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClassByName.jelly
new file mode 100644
index 0000000000..31133e5e67
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeClassByName.jelly
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeIt.jelly b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeIt.jelly
new file mode 100644
index 0000000000..ac5cb1734c
--- /dev/null
+++ b/test/src/test/resources/org/kohsuke/stapler/beanutils/TagTest/RootActionImpl/jellyStIncludeIt.jelly
@@ -0,0 +1,5 @@
+
+
+
+
+