Shagen Ogandzhanian
3 years ago
38 changed files with 2743 additions and 164 deletions
@ -1 +1 @@ |
|||||||
Subproject commit 6f678c440ed61acda22918acfb84d7356d3895ca |
Subproject commit 30f010967cd12643134a80269c7eb2de65b2332b |
@ -0,0 +1,74 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.attributes.builders |
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable |
||||||
|
import androidx.compose.runtime.NonRestartableComposable |
||||||
|
import org.jetbrains.compose.web.attributes.InputType |
||||||
|
import org.jetbrains.compose.web.dom.ElementScope |
||||||
|
import org.w3c.dom.HTMLElement |
||||||
|
import org.w3c.dom.HTMLInputElement |
||||||
|
import org.w3c.dom.HTMLTextAreaElement |
||||||
|
|
||||||
|
|
||||||
|
private val controlledInputsValuesWeakMap: JsWeakMap = js("new WeakMap();").unsafeCast<JsWeakMap>() |
||||||
|
|
||||||
|
internal fun restoreControlledInputState(type: InputType<*>, inputElement: HTMLInputElement) { |
||||||
|
if (controlledInputsValuesWeakMap.has(inputElement)) { |
||||||
|
if (type == InputType.Radio) { |
||||||
|
controlledRadioGroups[inputElement.name]?.forEach { radio -> |
||||||
|
radio.checked = controlledInputsValuesWeakMap.get(radio).toString().toBoolean() |
||||||
|
} |
||||||
|
inputElement.checked = controlledInputsValuesWeakMap.get(inputElement).toString().toBoolean() |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
if (type == InputType.Checkbox) { |
||||||
|
inputElement.checked = controlledInputsValuesWeakMap.get(inputElement).toString().toBoolean() |
||||||
|
} else { |
||||||
|
inputElement.value = controlledInputsValuesWeakMap.get(inputElement).toString() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal fun restoreControlledTextAreaState(element: HTMLTextAreaElement) { |
||||||
|
if (controlledInputsValuesWeakMap.has(element)) { |
||||||
|
element.value = controlledInputsValuesWeakMap.get(element).toString() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
internal fun <V : Any> saveControlledInputState(element: HTMLElement, value: V) { |
||||||
|
controlledInputsValuesWeakMap.set(element, value) |
||||||
|
|
||||||
|
if (element is HTMLInputElement) { |
||||||
|
updateRadioGroupIfNeeded(element) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// internal only for testing purposes. It actually should be private. |
||||||
|
internal val controlledRadioGroups = mutableMapOf<String, MutableSet<HTMLInputElement>>() |
||||||
|
|
||||||
|
private fun updateRadioGroupIfNeeded(element: HTMLInputElement) { |
||||||
|
if (element.type == "radio" && element.name.isNotEmpty()) { |
||||||
|
if (!controlledRadioGroups.containsKey(element.name)) { |
||||||
|
controlledRadioGroups[element.name] = mutableSetOf() |
||||||
|
} |
||||||
|
controlledRadioGroups[element.name]!!.add(element) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Composable |
||||||
|
@NonRestartableComposable |
||||||
|
internal fun ElementScope<HTMLInputElement>.DisposeRadioGroupEffect() { |
||||||
|
DisposableRefEffect { ref -> |
||||||
|
onDispose { |
||||||
|
controlledRadioGroups[ref.name]?.remove(ref) |
||||||
|
if (controlledRadioGroups[ref.name]?.isEmpty() == true) { |
||||||
|
controlledRadioGroups.remove(ref.name) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
import org.w3c.dom.css.CSS |
||||||
|
|
||||||
|
fun interface FilterFunction { |
||||||
|
fun apply(): String |
||||||
|
} |
||||||
|
|
||||||
|
interface FilterBuilder { |
||||||
|
fun blur(radius: CSSLengthValue) |
||||||
|
|
||||||
|
fun brightness(amount: Number) |
||||||
|
fun brightness(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue) |
||||||
|
fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue, blurRadius: CSSLengthValue) |
||||||
|
fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue, color: CSSColorValue) |
||||||
|
fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue, blurRadius: CSSLengthValue, color: CSSColorValue) |
||||||
|
|
||||||
|
fun contrast(amount: Number) |
||||||
|
fun contrast(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun grayscale(amount: Number) |
||||||
|
fun grayscale(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun hueRotate(angle: CSSAngleValue) |
||||||
|
|
||||||
|
fun invert(amount: Number) |
||||||
|
fun invert(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun opacity(amount: Number) |
||||||
|
fun opacity(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun saturate(amount: Number) |
||||||
|
fun saturate(amount: CSSPercentageValue) |
||||||
|
|
||||||
|
fun sepia(amount: Number) |
||||||
|
fun sepia(amount: CSSPercentageValue) |
||||||
|
} |
||||||
|
|
||||||
|
private class FilterBuilderImplementation : FilterBuilder { |
||||||
|
private val transformations = mutableListOf<FilterFunction>() |
||||||
|
|
||||||
|
override fun blur(radius: CSSLengthValue) { transformations.add { "blur($radius)" } } |
||||||
|
|
||||||
|
override fun brightness(amount: Number) { transformations.add { "brightness($amount)" } } |
||||||
|
override fun brightness(amount: CSSPercentageValue) { transformations.add { "brightness($amount)" } } |
||||||
|
|
||||||
|
override fun contrast(amount: Number) { transformations.add { "contrast($amount)" } } |
||||||
|
override fun contrast(amount: CSSPercentageValue) { transformations.add { "contrast($amount)" } } |
||||||
|
|
||||||
|
override fun grayscale(amount: Number) { transformations.add { "grayscale($amount)" } } |
||||||
|
override fun grayscale(amount: CSSPercentageValue) { transformations.add { "grayscale($amount)" } } |
||||||
|
|
||||||
|
override fun hueRotate(angle: CSSAngleValue) { transformations.add { "hue-rotate($angle)" } } |
||||||
|
|
||||||
|
override fun toString(): String { |
||||||
|
return transformations.joinToString(" ") { it.apply() } |
||||||
|
} |
||||||
|
|
||||||
|
override fun invert(amount: Number) { transformations.add { "invert($amount)" } } |
||||||
|
override fun invert(amount: CSSPercentageValue) { transformations.add { "invert($amount)" } } |
||||||
|
|
||||||
|
override fun opacity(amount: Number) { transformations.add { "opacity($amount)" } } |
||||||
|
override fun opacity(amount: CSSPercentageValue) { transformations.add { "opacity($amount)" } } |
||||||
|
|
||||||
|
override fun saturate(amount: Number) { transformations.add { "saturate($amount)" } } |
||||||
|
override fun saturate(amount: CSSPercentageValue) { transformations.add { "saturate($amount)" } } |
||||||
|
|
||||||
|
override fun sepia(amount: Number) { transformations.add { "sepia($amount)" } } |
||||||
|
override fun sepia(amount: CSSPercentageValue) { transformations.add { "sepia($amount)" } } |
||||||
|
|
||||||
|
override fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue) { |
||||||
|
transformations.add { "drop-shadow($offsetX $offsetY)" } |
||||||
|
} |
||||||
|
|
||||||
|
override fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue, blurRadius: CSSLengthValue) { |
||||||
|
transformations.add { "drop-shadow($offsetX $offsetY $blurRadius)" } |
||||||
|
} |
||||||
|
|
||||||
|
override fun dropShadow(offsetX: CSSLengthValue, offsetY: CSSLengthValue, color: CSSColorValue) { |
||||||
|
transformations.add { "drop-shadow($offsetX $offsetY $color)" } |
||||||
|
} |
||||||
|
|
||||||
|
override fun dropShadow( |
||||||
|
offsetX: CSSLengthValue, |
||||||
|
offsetY: CSSLengthValue, |
||||||
|
blurRadius: CSSLengthValue, |
||||||
|
color: CSSColorValue |
||||||
|
) { |
||||||
|
transformations.add { "drop-shadow($offsetX $offsetY $blurRadius $color)" } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
fun StyleBuilder.filter(filterContext: FilterBuilder.() -> Unit) { |
||||||
|
val builder = FilterBuilderImplementation() |
||||||
|
property("filter", builder.apply(filterContext).toString()) |
||||||
|
} |
||||||
|
|
||||||
|
|
@ -0,0 +1,138 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
|
||||||
|
fun interface TransformFunction { |
||||||
|
fun apply(): String |
||||||
|
} |
||||||
|
|
||||||
|
interface TransformBuilder { |
||||||
|
fun matrix(a: Number, b: Number, c: Number, d: Number, tx: Number, ty: Number): Boolean |
||||||
|
fun matrix3d( |
||||||
|
a1: Number, b1: Number, c1: Number, d1: Number, |
||||||
|
a2: Number, b2: Number, c2: Number, d2: Number, |
||||||
|
a3: Number, b3: Number, c3: Number, d3: Number, |
||||||
|
a4: Number, b4: Number, c4: Number, d4: Number |
||||||
|
): Boolean |
||||||
|
|
||||||
|
fun perspective(d: CSSLengthValue): Boolean |
||||||
|
fun rotate(a: CSSAngleValue): Boolean |
||||||
|
fun rotate3d(x: Number, y: Number, z: Number, a: CSSAngleValue): Boolean |
||||||
|
fun rotateX(a: CSSAngleValue): Boolean |
||||||
|
fun rotateY(a: CSSAngleValue): Boolean |
||||||
|
fun rotateZ(a: CSSAngleValue): Boolean |
||||||
|
fun scale(sx: Number): Boolean |
||||||
|
fun scale(sx: Number, sy: Number): Boolean |
||||||
|
fun scale3d(sx: Number, sy: Number, sz: Number): Boolean |
||||||
|
fun scaleX(s: Number): Boolean |
||||||
|
fun scaleY(s: Number): Boolean |
||||||
|
fun scaleZ(s: Number): Boolean |
||||||
|
fun skew(ax: CSSAngleValue): Boolean |
||||||
|
fun skew(ax: CSSAngleValue, ay: CSSAngleValue): Boolean |
||||||
|
fun skewX(a: CSSAngleValue): Boolean |
||||||
|
fun skewY(a: CSSAngleValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue, ty: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSLengthValue, ty: CSSPercentageValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue, ty: CSSLengthValue): Boolean |
||||||
|
fun translate(tx: CSSPercentageValue, ty: CSSPercentageValue): Boolean |
||||||
|
fun translate3d(tx: CSSLengthValue, ty: CSSLengthValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSLengthValue, ty: CSSPercentageValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSPercentageValue, ty: CSSLengthValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translate3d(tx: CSSPercentageValue, ty: CSSPercentageValue, tz: CSSLengthValue): Boolean |
||||||
|
fun translateX(tx: CSSLengthValue): Boolean |
||||||
|
fun translateX(tx: CSSPercentageValue): Boolean |
||||||
|
fun translateY(ty: CSSLengthValue): Boolean |
||||||
|
fun translateY(ty: CSSPercentageValue): Boolean |
||||||
|
fun translateZ(tz: CSSLengthValue): Boolean |
||||||
|
} |
||||||
|
|
||||||
|
private class TransformBuilderImplementation : TransformBuilder { |
||||||
|
private val transformations = mutableListOf<TransformFunction>() |
||||||
|
|
||||||
|
override fun matrix(a: Number, b: Number, c: Number, d: Number, tx: Number, ty: Number) = |
||||||
|
transformations.add { "matrix($a, $b, $c, $d, $tx, $ty)" } |
||||||
|
|
||||||
|
override fun matrix3d( |
||||||
|
a1: Number, b1: Number, c1: Number, d1: Number, |
||||||
|
a2: Number, b2: Number, c2: Number, d2: Number, |
||||||
|
a3: Number, b3: Number, c3: Number, d3: Number, |
||||||
|
a4: Number, b4: Number, c4: Number, d4: Number |
||||||
|
) = |
||||||
|
transformations.add { "matrix3d($a1, $b1, $c1, $d1, $a2, $b2, $c2, $d2, $a3, $b3, $c3, $d3, $a4, $b4, $c4, $d4)" } |
||||||
|
|
||||||
|
override fun perspective(d: CSSLengthValue) = transformations.add { "perspective($d)" } |
||||||
|
|
||||||
|
override fun rotate(a: CSSAngleValue) = transformations.add { "rotate($a)" } |
||||||
|
override fun rotate3d(x: Number, y: Number, z: Number, a: CSSAngleValue) = |
||||||
|
transformations.add({ "rotate3d($x, $y, $z, $a)" }) |
||||||
|
|
||||||
|
override fun rotateX(a: CSSAngleValue) = transformations.add { "rotateX($a)" } |
||||||
|
override fun rotateY(a: CSSAngleValue) = transformations.add { "rotateY($a)" } |
||||||
|
override fun rotateZ(a: CSSAngleValue) = transformations.add { "rotateZ($a)" } |
||||||
|
|
||||||
|
override fun scale(sx: Number) = transformations.add { "scale($sx)" } |
||||||
|
override fun scale(sx: Number, sy: Number) = transformations.add { "scale($sx, $sy)" } |
||||||
|
override fun scale3d(sx: Number, sy: Number, sz: Number) = |
||||||
|
transformations.add { "scale3d($sx, $sy, $sz)" } |
||||||
|
|
||||||
|
override fun scaleX(s: Number) = transformations.add { "scaleX($s)" } |
||||||
|
override fun scaleY(s: Number) = transformations.add { "scaleY($s)" } |
||||||
|
override fun scaleZ(s: Number) = transformations.add { "scaleZ($s)" } |
||||||
|
|
||||||
|
override fun skew(ax: CSSAngleValue) = transformations.add { "skew($ax)" } |
||||||
|
override fun skew(ax: CSSAngleValue, ay: CSSAngleValue) = transformations.add { "skew($ax, $ay)" } |
||||||
|
override fun skewX(a: CSSAngleValue) = transformations.add { "skewX($a)" } |
||||||
|
override fun skewY(a: CSSAngleValue) = transformations.add { "skewY($a)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue) = transformations.add { "translate($tx)" } |
||||||
|
override fun translate(tx: CSSPercentageValue) = transformations.add { "translate($tx)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue, ty: CSSLengthValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSLengthValue, ty: CSSPercentageValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSPercentageValue, ty: CSSLengthValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate(tx: CSSPercentageValue, ty: CSSPercentageValue) = |
||||||
|
transformations.add { "translate($tx, $ty)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSLengthValue, ty: CSSLengthValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSLengthValue, ty: CSSPercentageValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSPercentageValue, ty: CSSLengthValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translate3d(tx: CSSPercentageValue, ty: CSSPercentageValue, tz: CSSLengthValue) = |
||||||
|
transformations.add { "translate3d($tx, $ty, $tz)" } |
||||||
|
|
||||||
|
override fun translateX(tx: CSSLengthValue) = transformations.add { "translateX($tx)" } |
||||||
|
override fun translateX(tx: CSSPercentageValue) = transformations.add { "translateX($tx)" } |
||||||
|
|
||||||
|
override fun translateY(ty: CSSLengthValue) = transformations.add { "translateY($ty)" } |
||||||
|
override fun translateY(ty: CSSPercentageValue) = transformations.add { "translateY($ty)" } |
||||||
|
|
||||||
|
override fun translateZ(tz: CSSLengthValue) = transformations.add { "translateZ($tz)" } |
||||||
|
|
||||||
|
override fun toString(): String { |
||||||
|
return transformations.joinToString(" ") { it.apply() } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
fun StyleBuilder.transform(transformFunction: TransformBuilder.() -> Unit) { |
||||||
|
val transformBuilder = TransformBuilderImplementation() |
||||||
|
property("transform", transformBuilder.apply(transformFunction).toString()) |
||||||
|
} |
@ -0,0 +1,108 @@ |
|||||||
|
package org.jetbrains.compose.web.core.tests |
||||||
|
|
||||||
|
import androidx.compose.runtime.* |
||||||
|
import org.jetbrains.compose.web.dom.Div |
||||||
|
import org.jetbrains.compose.web.attributes.builders.controlledRadioGroups |
||||||
|
import org.jetbrains.compose.web.attributes.name |
||||||
|
import org.jetbrains.compose.web.dom.RadioInput |
||||||
|
import kotlin.test.Test |
||||||
|
import kotlin.test.assertEquals |
||||||
|
import kotlin.test.assertTrue |
||||||
|
|
||||||
|
class ControlledRadioGroupsTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
fun controlledRadioGroupGetsUpdated() = runTest { |
||||||
|
var countOfRadio by mutableStateOf(0) |
||||||
|
|
||||||
|
composition { |
||||||
|
repeat(countOfRadio) { |
||||||
|
key (it) { |
||||||
|
RadioInput(checked = false) { |
||||||
|
id("r$it") |
||||||
|
name("group1") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals(0, controlledRadioGroups.size) |
||||||
|
|
||||||
|
countOfRadio = 5 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(1, controlledRadioGroups.size) |
||||||
|
assertTrue(controlledRadioGroups.keys.first() == "group1") |
||||||
|
assertEquals(5, controlledRadioGroups["group1"]!!.size) |
||||||
|
|
||||||
|
countOfRadio = 2 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(1, controlledRadioGroups.size) |
||||||
|
assertTrue(controlledRadioGroups.keys.first() == "group1") |
||||||
|
assertEquals(2, controlledRadioGroups["group1"]!!.size) |
||||||
|
|
||||||
|
countOfRadio = 0 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(0, controlledRadioGroups.size) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun multipleControlledRadioGroupsGetUpdated() = runTest { |
||||||
|
var countOfRadioG1 by mutableStateOf(0) |
||||||
|
var countOfRadioG2 by mutableStateOf(0) |
||||||
|
|
||||||
|
composition { |
||||||
|
Div { |
||||||
|
repeat(countOfRadioG1) { |
||||||
|
key(it) { |
||||||
|
RadioInput(checked = false) { |
||||||
|
id("r1-$it") |
||||||
|
name("group1") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Div { |
||||||
|
repeat(countOfRadioG2) { |
||||||
|
key(it) { |
||||||
|
RadioInput(checked = false) { |
||||||
|
id("r2-$it") |
||||||
|
name("group2") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals(0, controlledRadioGroups.size) |
||||||
|
|
||||||
|
countOfRadioG1 = 5 |
||||||
|
countOfRadioG2 = 10 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(2, controlledRadioGroups.size) |
||||||
|
assertEquals(5, controlledRadioGroups["group1"]!!.size) |
||||||
|
assertEquals(10, controlledRadioGroups["group2"]!!.size) |
||||||
|
|
||||||
|
countOfRadioG2 = 2 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(2, controlledRadioGroups.size) |
||||||
|
assertEquals(5, controlledRadioGroups["group1"]!!.size) |
||||||
|
assertEquals(2, controlledRadioGroups["group2"]!!.size) |
||||||
|
|
||||||
|
countOfRadioG1 = 0 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(1, controlledRadioGroups.size) |
||||||
|
assertEquals(2, controlledRadioGroups["group2"]!!.size) |
||||||
|
|
||||||
|
countOfRadioG2 = 0 |
||||||
|
waitForRecompositionComplete() |
||||||
|
|
||||||
|
assertEquals(0, controlledRadioGroups.size) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,130 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.core.tests.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
import org.jetbrains.compose.web.core.tests.runTest |
||||||
|
import org.jetbrains.compose.web.css.* |
||||||
|
import org.jetbrains.compose.web.dom.Div |
||||||
|
import org.jetbrains.compose.web.dom.Img |
||||||
|
import kotlin.test.Test |
||||||
|
import kotlin.test.assertEquals |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
class FilterTests { |
||||||
|
@Test |
||||||
|
fun blur() = runTest { |
||||||
|
composition { |
||||||
|
Img(src = "icon.png", attrs = { style { filter { blur(10.px) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("blur(10px)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun brightness() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { brightness(1.75) } } }) |
||||||
|
Div({ style { filter { brightness(200.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("brightness(1.75)", nextChild().style.filter) |
||||||
|
assertEquals("brightness(200%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun contrast() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { contrast(2.75) } } }) |
||||||
|
Div({ style { filter { contrast(177.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("contrast(2.75)", nextChild().style.filter) |
||||||
|
assertEquals("contrast(177%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun grayscale() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { grayscale(0.15) } } }) |
||||||
|
Div({ style { filter { grayscale(90.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("grayscale(0.15)", nextChild().style.filter) |
||||||
|
assertEquals("grayscale(90%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun hueRotate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { hueRotate(90.deg) } } }) |
||||||
|
Div({ style { filter { hueRotate(0.5.turn) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("hue-rotate(90deg)", nextChild().style.filter) |
||||||
|
assertEquals("hue-rotate(0.5turn)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun invert() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { invert(0.75) } } }) |
||||||
|
Div({ style { filter { invert(30.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("invert(0.75)", nextChild().style.filter) |
||||||
|
assertEquals("invert(30%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun opacity() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { opacity(.25) } } }) |
||||||
|
Div({ style { filter { opacity(30.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("opacity(0.25)", nextChild().style.filter) |
||||||
|
assertEquals("opacity(30%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun saturate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { saturate(.25) } } }) |
||||||
|
Div({ style { filter { saturate(20.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("saturate(0.25)", nextChild().style.filter) |
||||||
|
assertEquals("saturate(20%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun sepia() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { sepia(.95) } } }) |
||||||
|
Div({ style { filter { sepia(80.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("sepia(0.95)", nextChild().style.filter) |
||||||
|
assertEquals("sepia(80%)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun dropShadow() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { filter { dropShadow(10.em, 5.px) } } }) |
||||||
|
Div({ style { filter { dropShadow(7.px, 2.px, 20.px) } } }) |
||||||
|
Div({ style { filter { dropShadow(7.px, 2.px, Color.yellow) } } }) |
||||||
|
Div({ style { filter { dropShadow(16.px, 16.px, 10.px, Color.black) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("drop-shadow(10em 5px)", nextChild().style.filter) |
||||||
|
assertEquals("drop-shadow(7px 2px 20px)", nextChild().style.filter) |
||||||
|
assertEquals("drop-shadow(yellow 7px 2px)", nextChild().style.filter) |
||||||
|
assertEquals("drop-shadow(black 16px 16px 10px)", nextChild().style.filter) |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,258 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
package org.jetbrains.compose.web.core.tests.css |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.ExperimentalComposeWebApi |
||||||
|
import org.jetbrains.compose.web.core.tests.runTest |
||||||
|
import org.jetbrains.compose.web.css.* |
||||||
|
import org.jetbrains.compose.web.dom.Div |
||||||
|
import kotlin.test.Test |
||||||
|
import kotlin.test.assertEquals |
||||||
|
|
||||||
|
@ExperimentalComposeWebApi |
||||||
|
class TransformTests { |
||||||
|
@Test |
||||||
|
fun matrix() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { matrix(1, 2, -1, 1, 80, 80) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("matrix(1, 2, -1, 1, 80, 80)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun matrix3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("matrix3d(1, 0, 0, 0, 0, 1, 6, 0, 0, 0, 1, 0, 50, 100, 0, 1.1)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun perspective() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { perspective(3.cm) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("perspective(3cm)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotate(3.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotate(3deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotate3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotate3d(1, 1, 0, 2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotate3d(1, 1, 0, 2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateX(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateX(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateX(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateX(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateX(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateX(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateY(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateY(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateY(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateY(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateY(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateY(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun rotateZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { rotateZ(60.deg) } } }) |
||||||
|
Div({ style { transform { rotateZ(-0.25.turn) } } }) |
||||||
|
Div({ style { transform { rotateZ(3.14.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("rotateZ(60deg)", nextChild().style.transform) |
||||||
|
assertEquals("rotateZ(-0.25turn)", nextChild().style.transform) |
||||||
|
assertEquals("rotateZ(3.14rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scale() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scale(0.6) } } }) |
||||||
|
Div({ style { transform { scale(0.2, 0.3) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scale(0.6)", nextChild().style.transform) |
||||||
|
assertEquals("scale(0.2, 0.3)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scale3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scale3d(0.2, 0.3, 0.1) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scale3d(0.2, 0.3, 0.1)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleX(0.5) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleX(0.5)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleY(0.7) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleY(0.7)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun scaleZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { scaleZ(0.12) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("scaleZ(0.12)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skew() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skew(2.deg) } } }) |
||||||
|
Div({ style { transform { skew(1.rad, 2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skew(2deg)", nextChild().style.transform) |
||||||
|
assertEquals("skew(1rad, 2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skewX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skewX(2.deg) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skewX(2deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun skewY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { skewY(2.rad) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("skewY(2rad)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translate() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translate(10.px) } } }) |
||||||
|
Div({ style { transform { translate(4.percent) } } }) |
||||||
|
Div({ style { transform { translate(2.percent, 10.px) } } }) |
||||||
|
Div({ style { transform { translate(10.px, 3.percent) } } }) |
||||||
|
Div({ style { transform { translate(20.px, 10.px) } } }) |
||||||
|
Div({ style { transform { translate(5.percent, 8.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translate(10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(4%)", nextChild().style.transform) |
||||||
|
assertEquals("translate(2%, 10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(10px, 3%)", nextChild().style.transform) |
||||||
|
assertEquals("translate(20px, 10px)", nextChild().style.transform) |
||||||
|
assertEquals("translate(5%, 8%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translate3d() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translate3d(2.percent, 10.px, 1.em) } } }) |
||||||
|
Div({ style { transform { translate3d(10.px, 3.percent, 2.em) } } }) |
||||||
|
Div({ style { transform { translate3d(20.px, 10.px, 3.em) } } }) |
||||||
|
Div({ style { transform { translate3d(5.percent, 8.percent, 4.em) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translate3d(2%, 10px, 1em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(10px, 3%, 2em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(20px, 10px, 3em)", nextChild().style.transform) |
||||||
|
assertEquals("translate3d(5%, 8%, 4em)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateX() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateX(10.px) } } }) |
||||||
|
Div({ style { transform { translateX(4.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateX(10px)", nextChild().style.transform) |
||||||
|
assertEquals("translateX(4%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateY() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateY(12.px) } } }) |
||||||
|
Div({ style { transform { translateY(3.percent) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateY(12px)", nextChild().style.transform) |
||||||
|
assertEquals("translateY(3%)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun translateZ() = runTest { |
||||||
|
composition { |
||||||
|
Div({ style { transform { translateZ(7.px) } } }) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("translateZ(7px)", nextChild().style.transform) |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
fun mutliples() = runTest { |
||||||
|
composition { |
||||||
|
Div({ |
||||||
|
style { |
||||||
|
transform { |
||||||
|
perspective(3.cm) |
||||||
|
translate(10.px, 3.px) |
||||||
|
rotateY(3.deg) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
assertEquals("perspective(3cm) translate(10px, 3px) rotateY(3deg)", nextChild().style.transform) |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,412 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package androidx.compose.web.sample.tests |
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue |
||||||
|
import androidx.compose.runtime.mutableStateOf |
||||||
|
import androidx.compose.runtime.remember |
||||||
|
import androidx.compose.runtime.setValue |
||||||
|
import org.jetbrains.compose.web.attributes.InputType |
||||||
|
import org.jetbrains.compose.web.attributes.name |
||||||
|
import org.jetbrains.compose.web.dom.* |
||||||
|
import org.jetbrains.compose.web.sample.tests.TestText |
||||||
|
import org.jetbrains.compose.web.sample.tests.testCase |
||||||
|
|
||||||
|
class ControlledInputsTests { |
||||||
|
|
||||||
|
val textInputHardcodedValueShouldNotChange by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextInput(value = "hardcoded", attrs = { |
||||||
|
id("textInput") |
||||||
|
onInput { |
||||||
|
onInputText = it.value |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textInputMutableValueShouldGetOverridden by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("InitialValue") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextInput(value = onInputText, attrs = { |
||||||
|
id("textInput") |
||||||
|
onInput { |
||||||
|
onInputText = "OVERRIDDEN VALUE" |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textInputMutableValueShouldChange by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("InitialValue") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextInput(value = onInputText, attrs = { |
||||||
|
id("textInput") |
||||||
|
onInput { |
||||||
|
onInputText = it.value |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textAreaHardcodedValueShouldNotChange by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextArea(value = "hardcoded", attrs = { |
||||||
|
id("textArea") |
||||||
|
onInput { |
||||||
|
onInputText = it.value |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textAreaMutableValueShouldGetOverridden by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("InitialValue") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextArea(value = onInputText, attrs = { |
||||||
|
id("textArea") |
||||||
|
onInput { |
||||||
|
onInputText = "OVERRIDDEN VALUE" |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textAreaMutableValueShouldChange by testCase { |
||||||
|
var onInputText by remember { mutableStateOf("InitialValue") } |
||||||
|
|
||||||
|
P { TestText(onInputText) } |
||||||
|
|
||||||
|
Div { |
||||||
|
TextArea(value = onInputText, attrs = { |
||||||
|
id("textArea") |
||||||
|
onInput { |
||||||
|
onInputText = it.value |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val checkBoxHardcodedNeverChanges by testCase { |
||||||
|
var checkClicked by remember { mutableStateOf(false) } |
||||||
|
|
||||||
|
P { TestText(checkClicked.toString()) } |
||||||
|
|
||||||
|
Div { |
||||||
|
CheckboxInput(checked = false) { |
||||||
|
id("checkbox") |
||||||
|
onInput { |
||||||
|
checkClicked = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val checkBoxMutableValueChanges by testCase { |
||||||
|
var checked by remember { mutableStateOf(false) } |
||||||
|
|
||||||
|
P { TestText(checked.toString()) } |
||||||
|
|
||||||
|
Div { |
||||||
|
CheckboxInput(checked = checked) { |
||||||
|
id("checkbox") |
||||||
|
onInput { |
||||||
|
checked = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val checkBoxDefaultCheckedChangesDoesntAffectState by testCase { |
||||||
|
var checked by remember { mutableStateOf(true) } |
||||||
|
|
||||||
|
P { TestText(checked.toString()) } |
||||||
|
|
||||||
|
Div { |
||||||
|
Input(type = InputType.Checkbox) { |
||||||
|
id("checkboxMirror") |
||||||
|
if (checked) defaultChecked() |
||||||
|
} |
||||||
|
|
||||||
|
Input(type = InputType.Checkbox) { |
||||||
|
id("checkboxMain") |
||||||
|
checked(checked) |
||||||
|
onInput { checked = it.value } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val radioHardcodedNeverChanges by testCase { |
||||||
|
Div { |
||||||
|
RadioInput(checked = true) { |
||||||
|
id("radio1") |
||||||
|
name("group1") |
||||||
|
} |
||||||
|
RadioInput(checked = false) { |
||||||
|
id("radio2") |
||||||
|
name("group1") |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val radioMutableCheckedChanges by testCase { |
||||||
|
var checked by remember { mutableStateOf(0) } |
||||||
|
|
||||||
|
TestText("Checked - $checked") |
||||||
|
|
||||||
|
Div { |
||||||
|
RadioInput(checked = checked == 1) { |
||||||
|
id("radio1") |
||||||
|
name("group1") |
||||||
|
onInput { checked = 1 } |
||||||
|
} |
||||||
|
RadioInput(checked = checked == 2) { |
||||||
|
id("radio2") |
||||||
|
name("group1") |
||||||
|
onInput { checked = 2 } |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val numberHardcodedNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
NumberInput(value = 5, min = 0, max = 100) { |
||||||
|
id("numberInput") |
||||||
|
onInput { |
||||||
|
typedValue = it.value.toString() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val numberMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf(5) } |
||||||
|
TestText(value = value.toString()) |
||||||
|
|
||||||
|
NumberInput(value = value, min = 0, max = 100) { |
||||||
|
id("numberInput") |
||||||
|
onInput { |
||||||
|
value = it.value!!.toInt() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val rangeHardcodedNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
RangeInput(value = 21) { |
||||||
|
id("rangeInput") |
||||||
|
onInput { |
||||||
|
typedValue = it.value.toString() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val rangeMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf(10) } |
||||||
|
|
||||||
|
TestText(value = value.toString()) |
||||||
|
|
||||||
|
RangeInput(value = value) { |
||||||
|
id("rangeInput") |
||||||
|
onInput { |
||||||
|
value = it.value!!.toInt() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val emailHardcodedNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
EmailInput(value = "a@a.abc") { |
||||||
|
id("emailInput") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val emailMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf("") } |
||||||
|
TestText(value = value) |
||||||
|
|
||||||
|
EmailInput(value = value) { |
||||||
|
id("emailInput") |
||||||
|
onInput { |
||||||
|
value = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val passwordHardcodedNeverChanges by testCase { |
||||||
|
var typeValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typeValue) |
||||||
|
|
||||||
|
PasswordInput(value = "123456") { |
||||||
|
id("passwordInput") |
||||||
|
onInput { |
||||||
|
typeValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val passwordMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf("") } |
||||||
|
TestText(value = value) |
||||||
|
|
||||||
|
EmailInput(value = value) { |
||||||
|
id("passwordInput") |
||||||
|
onInput { |
||||||
|
value = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val searchHardcodedNeverChanges by testCase { |
||||||
|
var typeValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typeValue) |
||||||
|
|
||||||
|
SearchInput(value = "hardcoded") { |
||||||
|
id("searchInput") |
||||||
|
onInput { |
||||||
|
typeValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val searchMutableChanges by testCase { |
||||||
|
var typeValue by remember { mutableStateOf("") } |
||||||
|
TestText(value = typeValue) |
||||||
|
|
||||||
|
SearchInput(value = typeValue) { |
||||||
|
id("searchInput") |
||||||
|
onInput { |
||||||
|
typeValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val telHardcodedNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
TelInput(value = "123456") { |
||||||
|
id("telInput") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val telMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf("") } |
||||||
|
TestText(value = value) |
||||||
|
|
||||||
|
TelInput(value = value) { |
||||||
|
id("telInput") |
||||||
|
onInput { |
||||||
|
value = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val urlHardcodedNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
UrlInput(value = "www.site.com") { |
||||||
|
id("urlInput") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val urlMutableChanges by testCase { |
||||||
|
var value by remember { mutableStateOf("") } |
||||||
|
TestText(value = value) |
||||||
|
|
||||||
|
UrlInput(value = value) { |
||||||
|
id("urlInput") |
||||||
|
onInput { |
||||||
|
value = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val hardcodedDateInputNeverChanges by testCase { |
||||||
|
var inputValue by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
TestText(inputValue) |
||||||
|
|
||||||
|
DateInput(value = "") { |
||||||
|
id("dateInput") |
||||||
|
onInput { |
||||||
|
inputValue = "onInput Caught" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val mutableDateInputChanges by testCase { |
||||||
|
var inputValue by remember { mutableStateOf("") } |
||||||
|
|
||||||
|
TestText(inputValue) |
||||||
|
|
||||||
|
DateInput(value = inputValue) { |
||||||
|
id("dateInput") |
||||||
|
onInput { |
||||||
|
inputValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val hardcodedTimeNeverChanges by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
TestText(typedValue) |
||||||
|
|
||||||
|
TimeInput(value = "14:00") { |
||||||
|
id("time") |
||||||
|
onInput { |
||||||
|
typedValue = "onInput Caught" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val mutableTimeChanges by testCase { |
||||||
|
var value by remember { mutableStateOf("") } |
||||||
|
|
||||||
|
TestText(value) |
||||||
|
|
||||||
|
TimeInput(value = value) { |
||||||
|
id("time") |
||||||
|
onInput { |
||||||
|
value = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,190 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package androidx.compose.web.sample.tests |
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue |
||||||
|
import androidx.compose.runtime.mutableStateOf |
||||||
|
import androidx.compose.runtime.remember |
||||||
|
import androidx.compose.runtime.setValue |
||||||
|
import org.jetbrains.compose.web.attributes.InputType |
||||||
|
import org.jetbrains.compose.web.attributes.name |
||||||
|
import org.jetbrains.compose.web.dom.* |
||||||
|
import org.jetbrains.compose.web.sample.tests.TestText |
||||||
|
import org.jetbrains.compose.web.sample.tests.testCase |
||||||
|
|
||||||
|
class UncontrolledInputsTests { |
||||||
|
|
||||||
|
val textInputDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var inputValue by remember { mutableStateOf("") } |
||||||
|
|
||||||
|
Input(type = InputType.Text) { |
||||||
|
|
||||||
|
id("textInput") |
||||||
|
defaultValue("defaultInputValue") |
||||||
|
|
||||||
|
attr("data-input-value", inputValue) |
||||||
|
|
||||||
|
onInput { |
||||||
|
inputValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val textAreaDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var inputValue by remember { mutableStateOf("") } |
||||||
|
|
||||||
|
TextArea { |
||||||
|
|
||||||
|
id("textArea") |
||||||
|
defaultValue("defaultTextAreaValue") |
||||||
|
|
||||||
|
attr("data-text-area-value", inputValue) |
||||||
|
|
||||||
|
onInput { |
||||||
|
inputValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val checkBoxDefaultCheckedRemainsTheSameButCheckedCanBeChanged by testCase { |
||||||
|
var checkedValue by remember { mutableStateOf(true) } |
||||||
|
|
||||||
|
Input(type = InputType.Checkbox) { |
||||||
|
id("checkbox") |
||||||
|
defaultChecked() |
||||||
|
value("checkbox-value") |
||||||
|
|
||||||
|
attr("data-checkbox", checkedValue.toString()) |
||||||
|
|
||||||
|
onInput { |
||||||
|
checkedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val radioDefaultCheckedRemainsTheSameButCheckedCanBeChanged by testCase { |
||||||
|
var checkedValue by remember { mutableStateOf("") } |
||||||
|
|
||||||
|
Input(type = InputType.Radio) { |
||||||
|
id("radio1") |
||||||
|
defaultChecked() |
||||||
|
value("radio-value1") |
||||||
|
name("radiogroup") |
||||||
|
|
||||||
|
attr("data-radio", checkedValue) |
||||||
|
|
||||||
|
onInput { |
||||||
|
checkedValue = "radio-value1" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Input(type = InputType.Radio) { |
||||||
|
id("radio2") |
||||||
|
value("radio-value2") |
||||||
|
name("radiogroup") |
||||||
|
|
||||||
|
attr("data-radio", checkedValue) |
||||||
|
|
||||||
|
onInput { |
||||||
|
checkedValue = "radio-value2" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val numberDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
TestText(value = "Value = $typedValue") |
||||||
|
|
||||||
|
Input(type = InputType.Number) { |
||||||
|
id("numberInput") |
||||||
|
defaultValue(11) |
||||||
|
onInput { |
||||||
|
typedValue = it.value.toString() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val rangeDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
|
||||||
|
TestText(value = "Value = $typedValue") |
||||||
|
|
||||||
|
Input(type = InputType.Range) { |
||||||
|
id("rangeInput") |
||||||
|
defaultValue(7) |
||||||
|
onInput { |
||||||
|
typedValue = it.value.toString() |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val emailDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = "Value = $typedValue") |
||||||
|
|
||||||
|
Input(type = InputType.Email) { |
||||||
|
id("emailInput") |
||||||
|
defaultValue("a@a.abc") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val passwordDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = "Value = $typedValue") |
||||||
|
|
||||||
|
Input(type = InputType.Password) { |
||||||
|
id("passwordInput") |
||||||
|
defaultValue("1111") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val searchDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = "Value = $typedValue") |
||||||
|
|
||||||
|
Input(type = InputType.Search) { |
||||||
|
id("searchInput") |
||||||
|
defaultValue("kotlin") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val telDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
Input(type = InputType.Tel) { |
||||||
|
id("telInput") |
||||||
|
defaultValue("123123") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
val urlDefaultValueRemainsTheSameButValueCanBeChanged by testCase { |
||||||
|
var typedValue by remember { mutableStateOf("None") } |
||||||
|
TestText(value = typedValue) |
||||||
|
|
||||||
|
Input(type = InputType.Url) { |
||||||
|
id("urlInput") |
||||||
|
defaultValue("www.site.com") |
||||||
|
onInput { |
||||||
|
typedValue = it.value |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,507 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.tests.integration |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.tests.integration.common.BaseIntegrationTests |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.ResolveDrivers |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.openTestPage |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.waitTextToBe |
||||||
|
import org.junit.jupiter.api.Assumptions |
||||||
|
import org.openqa.selenium.By |
||||||
|
import org.openqa.selenium.Keys |
||||||
|
import org.openqa.selenium.WebDriver |
||||||
|
import org.openqa.selenium.chrome.ChromeDriver |
||||||
|
|
||||||
|
class ControlledInputsTests : BaseIntegrationTests() { |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textInputHardcodedValueShouldNotChange(driver: WebDriver) { |
||||||
|
driver.openTestPage("textInputHardcodedValueShouldNotChange") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val controlledTextInput = driver.findElement(By.id("textInput")) |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("A") |
||||||
|
driver.waitTextToBe(value = "hardcodedA") |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("B") |
||||||
|
driver.waitTextToBe(value = "hardcodedB") |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("C") |
||||||
|
driver.waitTextToBe(value = "hardcodedC") |
||||||
|
|
||||||
|
check(controlledTextInput.getAttribute("value") == "hardcoded") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textInputMutableValueShouldGetOverridden(driver: WebDriver) { |
||||||
|
driver.openTestPage("textInputMutableValueShouldGetOverridden") |
||||||
|
driver.waitTextToBe(value = "InitialValue") |
||||||
|
|
||||||
|
val controlledTextInput = driver.findElement(By.id("textInput")) |
||||||
|
controlledTextInput.sendKeys("ABC") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "OVERRIDDEN VALUE") |
||||||
|
check(controlledTextInput.getAttribute("value") == "OVERRIDDEN VALUE") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textInputMutableValueShouldChange(driver: WebDriver) { |
||||||
|
driver.openTestPage("textInputMutableValueShouldChange") |
||||||
|
driver.waitTextToBe(value = "InitialValue") |
||||||
|
|
||||||
|
val controlledTextInput = driver.findElement(By.id("textInput")) |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("A") |
||||||
|
driver.waitTextToBe(value = "InitialValueA") |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("B") |
||||||
|
driver.waitTextToBe(value = "InitialValueAB") |
||||||
|
|
||||||
|
controlledTextInput.sendKeys("C") |
||||||
|
driver.waitTextToBe(value = "InitialValueABC") |
||||||
|
|
||||||
|
check(controlledTextInput.getAttribute("value") == "InitialValueABC") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textAreaHardcodedValueShouldNotChange(driver: WebDriver) { |
||||||
|
driver.openTestPage("textAreaHardcodedValueShouldNotChange") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val controlledTextArea = driver.findElement(By.id("textArea")) |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("A") |
||||||
|
driver.waitTextToBe(value = "hardcodedA") |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("B") |
||||||
|
driver.waitTextToBe(value = "hardcodedB") |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("C") |
||||||
|
driver.waitTextToBe(value = "hardcodedC") |
||||||
|
|
||||||
|
check(controlledTextArea.getAttribute("value") == "hardcoded") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textAreaMutableValueShouldGetOverridden(driver: WebDriver) { |
||||||
|
driver.openTestPage("textAreaMutableValueShouldGetOverridden") |
||||||
|
driver.waitTextToBe(value = "InitialValue") |
||||||
|
|
||||||
|
val controlledTextArea = driver.findElement(By.id("textArea")) |
||||||
|
controlledTextArea.sendKeys("ABC") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "OVERRIDDEN VALUE") |
||||||
|
check(controlledTextArea.getAttribute("value") == "OVERRIDDEN VALUE") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textAreaMutableValueShouldChange(driver: WebDriver) { |
||||||
|
driver.openTestPage("textAreaMutableValueShouldChange") |
||||||
|
driver.waitTextToBe(value = "InitialValue") |
||||||
|
|
||||||
|
val controlledTextArea = driver.findElement(By.id("textArea")) |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("A") |
||||||
|
driver.waitTextToBe(value = "InitialValueA") |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("B") |
||||||
|
driver.waitTextToBe(value = "InitialValueAB") |
||||||
|
|
||||||
|
controlledTextArea.sendKeys("C") |
||||||
|
driver.waitTextToBe(value = "InitialValueABC") |
||||||
|
|
||||||
|
check(controlledTextArea.getAttribute("value") == "InitialValueABC") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun checkBoxHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("checkBoxHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "false") |
||||||
|
|
||||||
|
val checkbox = driver.findElement(By.id("checkbox")) |
||||||
|
check(!checkbox.isSelected) |
||||||
|
|
||||||
|
checkbox.click() |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "true") // input received but ignored |
||||||
|
check(!checkbox.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun checkBoxMutableValueChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("checkBoxMutableValueChanges") |
||||||
|
driver.waitTextToBe(value = "false") |
||||||
|
|
||||||
|
val checkbox = driver.findElement(By.id("checkbox")) |
||||||
|
check(!checkbox.isSelected) |
||||||
|
|
||||||
|
checkbox.click() |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "true") |
||||||
|
check(checkbox.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun checkBoxDefaultCheckedChangesDoesntAffectState(driver: WebDriver) { |
||||||
|
driver.openTestPage("checkBoxDefaultCheckedChangesDoesntAffectState") |
||||||
|
driver.waitTextToBe(value = "true") |
||||||
|
|
||||||
|
val mainCheckbox = driver.findElement(By.id("checkboxMain")) |
||||||
|
val mirrorCheckbox = driver.findElement(By.id("checkboxMirror")) |
||||||
|
|
||||||
|
check(mainCheckbox.isSelected) |
||||||
|
check(mirrorCheckbox.isSelected) |
||||||
|
|
||||||
|
mirrorCheckbox.click() |
||||||
|
driver.waitTextToBe(value = "true") |
||||||
|
check(!mirrorCheckbox.isSelected) |
||||||
|
check(mainCheckbox.isSelected) |
||||||
|
|
||||||
|
mainCheckbox.click() |
||||||
|
driver.waitTextToBe(value = "false") |
||||||
|
check(!mainCheckbox.isSelected) |
||||||
|
check(!mirrorCheckbox.isSelected) |
||||||
|
|
||||||
|
mainCheckbox.click() |
||||||
|
driver.waitTextToBe(value = "true") |
||||||
|
check(mainCheckbox.isSelected) |
||||||
|
check(!mirrorCheckbox.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun radioHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("radioHardcodedNeverChanges") |
||||||
|
|
||||||
|
val radio1 = driver.findElement(By.id("radio1")) |
||||||
|
val radio2 = driver.findElement(By.id("radio2")) |
||||||
|
|
||||||
|
check(radio1.isSelected) |
||||||
|
check(!radio2.isSelected) |
||||||
|
|
||||||
|
check(radio1.getAttribute("name") == radio2.getAttribute("name")) |
||||||
|
check(radio1.getAttribute("name") == "group1") |
||||||
|
check(radio2.getAttribute("name") == "group1") |
||||||
|
|
||||||
|
radio2.click() |
||||||
|
|
||||||
|
check(radio1.isSelected) |
||||||
|
check(!radio2.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun radioMutableCheckedChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("radioMutableCheckedChanges") |
||||||
|
driver.waitTextToBe(value = "Checked - 0") |
||||||
|
|
||||||
|
val radio1 = driver.findElement(By.id("radio1")) |
||||||
|
val radio2 = driver.findElement(By.id("radio2")) |
||||||
|
|
||||||
|
check(!radio1.isSelected) |
||||||
|
check(!radio2.isSelected) |
||||||
|
|
||||||
|
radio2.click() |
||||||
|
driver.waitTextToBe(value = "Checked - 2") |
||||||
|
|
||||||
|
check(!radio1.isSelected) |
||||||
|
check(radio2.isSelected) |
||||||
|
|
||||||
|
radio1.click() |
||||||
|
driver.waitTextToBe(value = "Checked - 1") |
||||||
|
|
||||||
|
check(radio1.isSelected) |
||||||
|
check(!radio2.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun numberHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("numberHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("numberInput")) |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "5") |
||||||
|
|
||||||
|
numberInput.sendKeys("1") |
||||||
|
driver.waitTextToBe(value = "51") |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "5") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun numberMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("numberMutableChanges") |
||||||
|
driver.waitTextToBe(value = "5") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("numberInput")) |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "5") |
||||||
|
|
||||||
|
numberInput.sendKeys("1") |
||||||
|
driver.waitTextToBe(value = "51") |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "51") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun rangeHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("rangeHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("rangeInput")) |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "21") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "22") |
||||||
|
check(numberInput.getAttribute("value") == "21") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "22") |
||||||
|
check(numberInput.getAttribute("value") == "21") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun rangeMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("rangeMutableChanges") |
||||||
|
driver.waitTextToBe(value = "10") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("rangeInput")) |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "10") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "11") |
||||||
|
check(numberInput.getAttribute("value") == "11") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "12") |
||||||
|
check(numberInput.getAttribute("value") == "12") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun emailHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("emailHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val emailInput = driver.findElement(By.id("emailInput")) |
||||||
|
check(emailInput.getAttribute("value") == "a@a.abc") |
||||||
|
|
||||||
|
emailInput.sendKeys("@") |
||||||
|
driver.waitTextToBe(value = "a@a.abc@") |
||||||
|
|
||||||
|
check(emailInput.getAttribute("value") == "a@a.abc") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun emailMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("emailMutableChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val emailInput = driver.findElement(By.id("emailInput")) |
||||||
|
check(emailInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
emailInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "a") |
||||||
|
|
||||||
|
check(emailInput.getAttribute("value") == "a") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun passwordHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("passwordHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val passwordInput = driver.findElement(By.id("passwordInput")) |
||||||
|
check(passwordInput.getAttribute("value") == "123456") |
||||||
|
|
||||||
|
passwordInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "123456a") |
||||||
|
|
||||||
|
check(passwordInput.getAttribute("value") == "123456") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun passwordMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("passwordMutableChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val passwordInput = driver.findElement(By.id("passwordInput")) |
||||||
|
check(passwordInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
passwordInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "a") |
||||||
|
|
||||||
|
check(passwordInput.getAttribute("value") == "a") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun searchHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("searchHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val searchInput = driver.findElement(By.id("searchInput")) |
||||||
|
check(searchInput.getAttribute("value") == "hardcoded") |
||||||
|
|
||||||
|
searchInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "hardcodeda") |
||||||
|
|
||||||
|
check(searchInput.getAttribute("value") == "hardcoded") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun searchMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("searchMutableChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val searchInput = driver.findElement(By.id("searchInput")) |
||||||
|
check(searchInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
searchInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "a") |
||||||
|
|
||||||
|
check(searchInput.getAttribute("value") == "a") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun telHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("telHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val telInput = driver.findElement(By.id("telInput")) |
||||||
|
check(telInput.getAttribute("value") == "123456") |
||||||
|
|
||||||
|
telInput.sendKeys("7") |
||||||
|
driver.waitTextToBe(value = "1234567") |
||||||
|
|
||||||
|
check(telInput.getAttribute("value") == "123456") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun telMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("telMutableChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val telInput = driver.findElement(By.id("telInput")) |
||||||
|
check(telInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
telInput.sendKeys("1") |
||||||
|
driver.waitTextToBe(value = "1") |
||||||
|
|
||||||
|
check(telInput.getAttribute("value") == "1") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun urlHardcodedNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("urlHardcodedNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val urlInput = driver.findElement(By.id("urlInput")) |
||||||
|
check(urlInput.getAttribute("value") == "www.site.com") |
||||||
|
|
||||||
|
urlInput.sendKeys("a") |
||||||
|
driver.waitTextToBe(value = "www.site.coma") |
||||||
|
|
||||||
|
check(urlInput.getAttribute("value") == "www.site.com") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun urlMutableChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("urlMutableChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val urlInput = driver.findElement(By.id("urlInput")) |
||||||
|
check(urlInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
urlInput.sendKeys("w") |
||||||
|
driver.waitTextToBe(value = "w") |
||||||
|
|
||||||
|
check(urlInput.getAttribute("value") == "w") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun hardcodedDateInputNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("hardcodedDateInputNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val dateInput = driver.findElement(By.id("dateInput")) |
||||||
|
check(dateInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
driver.sendKeysForDateInput(dateInput, 2021, 10, 22) |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "onInput Caught") |
||||||
|
check(dateInput.getAttribute("value") == "") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun mutableDateInputChanges(driver: WebDriver) { |
||||||
|
// We skip chrome, since for some reason `sendKeys` doesn't work as expected when used for Controlled Input in Chrome |
||||||
|
Assumptions.assumeTrue( |
||||||
|
driver !is ChromeDriver, |
||||||
|
"chrome driver doesn't work properly when using sendKeys on Controlled Input" |
||||||
|
) |
||||||
|
|
||||||
|
driver.openTestPage("mutableDateInputChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val dateInput = driver.findElement(By.id("dateInput")) |
||||||
|
check(dateInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
driver.sendKeysForDateInput(dateInput, 2021, 10, 22) |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "2021-10-22") |
||||||
|
check(dateInput.getAttribute("value") == "2021-10-22") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun hardcodedTimeNeverChanges(driver: WebDriver) { |
||||||
|
driver.openTestPage("hardcodedTimeNeverChanges") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val timeInput = driver.findElement(By.id("time")) |
||||||
|
check(timeInput.getAttribute("value") == "14:00") |
||||||
|
|
||||||
|
timeInput.sendKeys("18:31") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "onInput Caught") |
||||||
|
check(timeInput.getAttribute("value") == "14:00") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun mutableTimeChanges(driver: WebDriver) { |
||||||
|
// We skip chrome, since for some reason `sendKeys` doesn't work as expected when used for Controlled Input in Chrome |
||||||
|
Assumptions.assumeTrue( |
||||||
|
driver !is ChromeDriver, |
||||||
|
"chrome driver doesn't work properly when using sendKeys on Controlled Input" |
||||||
|
) |
||||||
|
|
||||||
|
driver.openTestPage("mutableTimeChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val timeInput = driver.findElement(By.id("time")) |
||||||
|
check(timeInput.getAttribute("value") == "") |
||||||
|
|
||||||
|
timeInput.sendKeys("18:31") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "18:31") |
||||||
|
check(timeInput.getAttribute("value") == "18:31") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun timeInputSendKeysOnChromeFailingTest(driver: WebDriver) { |
||||||
|
Assumptions.assumeTrue( |
||||||
|
driver is ChromeDriver, |
||||||
|
"this a `failing test for Chrome only` to catch when issue with sendKeys is resolved" |
||||||
|
) |
||||||
|
driver.openTestPage("mutableTimeChanges") |
||||||
|
driver.waitTextToBe(value = "") |
||||||
|
|
||||||
|
val timeInput = driver.findElement(By.id("time")) |
||||||
|
|
||||||
|
timeInput.sendKeys("18:31") |
||||||
|
driver.waitTextToBe(value = "18:03") // it should be 18:31, but this is a failing test, so wrong value is expected |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,208 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.web.tests.integration |
||||||
|
|
||||||
|
import org.jetbrains.compose.web.tests.integration.common.BaseIntegrationTests |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.ResolveDrivers |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.openTestPage |
||||||
|
import org.jetbrains.compose.web.tests.integration.common.waitTextToBe |
||||||
|
import org.openqa.selenium.By |
||||||
|
import org.openqa.selenium.Keys |
||||||
|
import org.openqa.selenium.WebDriver |
||||||
|
|
||||||
|
class UncontrolledInputsTests : BaseIntegrationTests() { |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textInputDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("textInputDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
|
||||||
|
val input = driver.findElement(By.id("textInput")) |
||||||
|
check(input.getAttribute("value") == "defaultInputValue") |
||||||
|
|
||||||
|
input.sendKeys("-TypedText") |
||||||
|
|
||||||
|
val inputHtml = driver.outerHtmlOfElementWithId("textInput") |
||||||
|
|
||||||
|
check(inputHtml.contains("value=\"defaultInputValue\"")) |
||||||
|
check(input.getAttribute("value") == "defaultInputValue-TypedText") // this checks the `value` property of the input |
||||||
|
check(input.getAttribute("data-input-value") == "defaultInputValue-TypedText") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun textAreaDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("textAreaDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
|
||||||
|
val textArea = driver.findElement(By.id("textArea")) |
||||||
|
check(textArea.getAttribute("value") == "defaultTextAreaValue") |
||||||
|
|
||||||
|
textArea.sendKeys("-TypedText") |
||||||
|
|
||||||
|
val innerTextOfTextArea = driver.outerHtmlOfElementWithId("textArea") |
||||||
|
|
||||||
|
check(innerTextOfTextArea.contains(">defaultTextAreaValue</")) // inner text keeps default value |
||||||
|
check(textArea.getAttribute("value") == "defaultTextAreaValue-TypedText") // this checks the `value` property of the textarea |
||||||
|
check(textArea.getAttribute("data-text-area-value") == "defaultTextAreaValue-TypedText") |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun checkBoxDefaultCheckedRemainsTheSameButCheckedCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("checkBoxDefaultCheckedRemainsTheSameButCheckedCanBeChanged") |
||||||
|
|
||||||
|
val checkbox = driver.findElement(By.id("checkbox")) |
||||||
|
|
||||||
|
val innerTextOfCheckbox1 = driver.outerHtmlOfElementWithId("checkbox") |
||||||
|
check(innerTextOfCheckbox1.contains("checked")) |
||||||
|
check(checkbox.getAttribute("value") == "checkbox-value") |
||||||
|
check(checkbox.getAttribute("data-checkbox") == "true") |
||||||
|
check(checkbox.isSelected) |
||||||
|
|
||||||
|
checkbox.click() |
||||||
|
|
||||||
|
val innerTextOfCheckbox2 = driver.outerHtmlOfElementWithId("checkbox") |
||||||
|
check(innerTextOfCheckbox2.contains("checked")) |
||||||
|
check(checkbox.getAttribute("value") == "checkbox-value") |
||||||
|
check(checkbox.getAttribute("data-checkbox") == "false") |
||||||
|
check(!checkbox.isSelected) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun radioDefaultCheckedRemainsTheSameButCheckedCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("radioDefaultCheckedRemainsTheSameButCheckedCanBeChanged") |
||||||
|
|
||||||
|
val radio1 = driver.findElement(By.id("radio1")) |
||||||
|
val radio2 = driver.findElement(By.id("radio2")) |
||||||
|
|
||||||
|
check(radio1.isSelected) |
||||||
|
check(!radio2.isSelected) |
||||||
|
|
||||||
|
check(driver.outerHtmlOfElementWithId("radio1").contains("checked")) |
||||||
|
check(!driver.outerHtmlOfElementWithId("radio2").contains("checked")) |
||||||
|
|
||||||
|
radio2.click() |
||||||
|
|
||||||
|
check(!radio1.isSelected) |
||||||
|
check(radio2.isSelected) |
||||||
|
|
||||||
|
check(driver.outerHtmlOfElementWithId("radio1").contains("checked")) |
||||||
|
check(!driver.outerHtmlOfElementWithId("radio2").contains("checked")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun numberDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("numberDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "Value = None") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("numberInput")) |
||||||
|
check(numberInput.getAttribute("value") == "11") |
||||||
|
|
||||||
|
numberInput.sendKeys("5") |
||||||
|
driver.waitTextToBe(value = "Value = 511") |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "511") |
||||||
|
check(driver.outerHtmlOfElementWithId("numberInput").contains("value=\"11\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun rangeDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("rangeDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "Value = None") |
||||||
|
|
||||||
|
val numberInput = driver.findElement(By.id("rangeInput")) |
||||||
|
check(numberInput.getAttribute("value") == "7") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "Value = 8") |
||||||
|
|
||||||
|
numberInput.sendKeys(Keys.ARROW_RIGHT) |
||||||
|
driver.waitTextToBe(value = "Value = 9") |
||||||
|
|
||||||
|
check(numberInput.getAttribute("value") == "9") |
||||||
|
check(driver.outerHtmlOfElementWithId("rangeInput").contains("value=\"7\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun emailDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("emailDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "Value = None") |
||||||
|
|
||||||
|
val emailInput = driver.findElement(By.id("emailInput")) |
||||||
|
check(emailInput.getAttribute("value") == "a@a.abc") |
||||||
|
|
||||||
|
emailInput.clear() |
||||||
|
emailInput.sendKeys("u@u.com") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "Value = u@u.com") |
||||||
|
check(emailInput.getAttribute("value") == "u@u.com") |
||||||
|
|
||||||
|
check(driver.outerHtmlOfElementWithId("emailInput").contains("value=\"a@a.abc\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun passwordDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("passwordDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "Value = None") |
||||||
|
|
||||||
|
val passwordInput = driver.findElement(By.id("passwordInput")) |
||||||
|
check(passwordInput.getAttribute("value") == "1111") |
||||||
|
|
||||||
|
passwordInput.clear() |
||||||
|
passwordInput.sendKeys("a") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "Value = a") |
||||||
|
check(passwordInput.getAttribute("value") == "a") |
||||||
|
|
||||||
|
check(driver.outerHtmlOfElementWithId("passwordInput").contains("value=\"1111\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun searchDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("searchDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "Value = None") |
||||||
|
|
||||||
|
val searchInput = driver.findElement(By.id("searchInput")) |
||||||
|
check(searchInput.getAttribute("value") == "kotlin") |
||||||
|
|
||||||
|
searchInput.clear() |
||||||
|
searchInput.sendKeys("j") |
||||||
|
driver.waitTextToBe(value = "Value = j") |
||||||
|
|
||||||
|
check(searchInput.getAttribute("value") == "j") |
||||||
|
|
||||||
|
check(driver.outerHtmlOfElementWithId("searchInput").contains("value=\"kotlin\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun telDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("telDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val telInput = driver.findElement(By.id("telInput")) |
||||||
|
check(telInput.getAttribute("value") == "123123") |
||||||
|
|
||||||
|
telInput.clear() |
||||||
|
telInput.sendKeys("987654321") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "987654321") |
||||||
|
check(telInput.getAttribute("value") == "987654321") |
||||||
|
check(driver.outerHtmlOfElementWithId("telInput").contains("value=\"123123\"")) |
||||||
|
} |
||||||
|
|
||||||
|
@ResolveDrivers |
||||||
|
fun urlDefaultValueRemainsTheSameButValueCanBeChanged(driver: WebDriver) { |
||||||
|
driver.openTestPage("urlDefaultValueRemainsTheSameButValueCanBeChanged") |
||||||
|
driver.waitTextToBe(value = "None") |
||||||
|
|
||||||
|
val urlInput = driver.findElement(By.id("urlInput")) |
||||||
|
check(urlInput.getAttribute("value") == "www.site.com") |
||||||
|
|
||||||
|
urlInput.clear() |
||||||
|
urlInput.sendKeys("google.com") |
||||||
|
|
||||||
|
driver.waitTextToBe(value = "google.com") |
||||||
|
check(urlInput.getAttribute("value") == "google.com") |
||||||
|
check(driver.outerHtmlOfElementWithId("urlInput").contains("value=\"www.site.com\"")) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue