diff --git a/api/assertj-jsoup.api b/api/assertj-jsoup.api index c9ec1f2..873525c 100644 --- a/api/assertj-jsoup.api +++ b/api/assertj-jsoup.api @@ -47,6 +47,7 @@ public class io/github/ulfs/assertj/jsoup/DocumentAssert : org/assertj/core/api/ public final fun elementHasClass (Ljava/lang/String;Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; public final fun elementHasHtml (Ljava/lang/String;Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; public final fun elementHasHtml (Ljava/lang/String;[Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; + public final fun elementHasTag (Ljava/lang/String;Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; public final fun elementHasText (Ljava/lang/String;Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; public final fun elementHasText (Ljava/lang/String;[Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; public final fun elementMatchesHtml (Ljava/lang/String;Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/DocumentAssert; @@ -90,6 +91,7 @@ public final class io/github/ulfs/assertj/jsoup/NodeAssertionsSpec { public final fun hasHtml (Ljava/lang/Object;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; public final fun hasHtml (Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; public final fun hasHtml ([Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; + public final fun hasTag (Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; public final fun hasText (Ljava/lang/Object;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; public final fun hasText (Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; public final fun hasText ([Ljava/lang/String;)Lio/github/ulfs/assertj/jsoup/NodeAssertionsSpec; diff --git a/src/main/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssert.kt b/src/main/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssert.kt index ccfd556..522d66d 100644 --- a/src/main/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssert.kt +++ b/src/main/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssert.kt @@ -314,6 +314,33 @@ public open class DocumentAssert( } } + public fun elementHasTag(cssSelector: String, tagName: String): DocumentAssert = apply { + isNotNull + + val selection = actual.select(cssSelector) + if (selection.isEmpty()) { + failWithElementNotFound(cssSelector) + return this + } + + selection.forEach { + if (it.tagName() != tagName) { + failWithMessage( + "%nExpecting element for%n" + + " <%s>%n" + + "to be of tag%n" + + " <%s>%n" + + "but was%n" + + " <%s>", + cssSelector, + tagName, + it.tagName(), + maskSelection(selection) + ) + } + } + } + public fun elementContainsText(cssSelector: String, substring: String): DocumentAssert = apply { isNotNull diff --git a/src/main/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpec.kt b/src/main/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpec.kt index cd14356..02c95b6 100644 --- a/src/main/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpec.kt +++ b/src/main/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpec.kt @@ -78,5 +78,9 @@ public data class NodeAssertionsSpec( spec.assert() } + public fun hasTag(tagName: String): NodeAssertionsSpec = apply { + softAssertions.assertThat(document).elementHasTag(cssSelector, tagName) + } + public fun attribute(attributeName: String): NodeAssertionsSpec = attribute(attributeName) { exists() } } diff --git a/src/test/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssertElementHasTagTest.kt b/src/test/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssertElementHasTagTest.kt new file mode 100644 index 0000000..ee8ad23 --- /dev/null +++ b/src/test/kotlin/io/github/ulfs/assertj/jsoup/DocumentAssertElementHasTagTest.kt @@ -0,0 +1,89 @@ +package io.github.ulfs.assertj.jsoup + +import io.github.ulfs.assertj.jsoup.Assertions.assertThat +import io.github.ulfs.assertj.jsoup.test.hasErrorWithMessage +import io.github.ulfs.assertj.jsoup.test.hasOneError +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.assertj.core.error.AssertJMultipleFailuresError +import org.assertj.core.util.FailureMessages.actualIsNull +import org.jsoup.nodes.Document +import kotlin.test.Test + +class DocumentAssertElementHasTagTest { + + @Test + fun `should fail if element is null`() { + // given + val nullDocument: Document? = null + + // when / then + assertThatThrownBy { + assertThat(nullDocument).elementHasTag(".class", "div") + } + .isInstanceOf(AssertionError::class.java) + .hasMessage(actualIsNull()) + } + + @Test + fun `should fail if element does not exist`() { + // given + val document = JsoupUtils.parse("") + + // when / then + assertThatThrownBy { + assertThat(document, true) { + elementHasTag(".class", "div") + } + } + .isInstanceOf(AssertJMultipleFailuresError::class.java) + .hasOneError() + .hasErrorWithMessage( + """ + + Expecting element for + <.class> + but found nothing + """.trimIndent() + ) + } + + @Test + fun `should pass if element has tag`() { + // given + val document: Document = JsoupUtils.parse("""
text
""") + + // when + assertThat(document, true) { + elementHasTag(".class", "div") + } + + // then + // no exception is thrown + } + + @Test + fun `should fail if element is of a different tag`() { + // given + val document: Document = JsoupUtils.parse("""different""") + + // when / then + assertThatThrownBy { + assertThat(document, true) { + elementHasTag(".class", "div") + } + } + .isInstanceOf(AssertionError::class.java) + .hasOneError() + .hasErrorWithMessage( + """ + + Expecting element for + <.class> + to be of tag +
+ but was + + """.trimIndent() + ) + } +} diff --git a/src/test/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpecTest.kt b/src/test/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpecTest.kt index 8e85703..b762958 100644 --- a/src/test/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpecTest.kt +++ b/src/test/kotlin/io/github/ulfs/assertj/jsoup/NodeAssertionsSpecTest.kt @@ -299,6 +299,19 @@ class NodeAssertionsSpecTest { verify { softAssertions.assertThat(any()).elementAttributeExists("selector", "attr") } } + @Test + fun `should call elementHasTag`() { + // given + every { softAssertions.assertThat(any()).elementHasTag(any(), any()) } returns dummySoftAssertions() + + val spec = spec() + + // when + spec.hasTag("tag") + + // then + verify { softAssertions.assertThat(any()).elementHasTag("selector", "tag") } + } private fun spec() = NodeAssertionsSpec( softAssertions = softAssertions,