@@ -16,6 +16,7 @@ let K1ConnectionPipelines;
let physicalRecoveryConnectionDetail ;
let shouldRenderK1OperationalPanels ;
let K1ProvisioningPipeline ;
let K1WifiPasswordField ;
let RuntimeActionFenceTestContext ;
let LOCAL _OPERATION _PROGRESS _DELAY _MILLISECONDS ;
let emptySearchPresentation ;
@@ -102,6 +103,9 @@ before(async () => {
logLevel : "silent" ,
server : { middlewareMode : true } ,
} ) ;
( { K1WifiPasswordField } = await server . ssrLoadModule (
"@xgrids-k1/frontend/components/K1WifiPasswordField.tsx" ,
) ) ;
( { normalizeXgridsK1MissionState } = await server . ssrLoadModule (
"@xgrids-k1/frontend/runtimeContext.tsx" ,
) ) ;
@@ -277,7 +281,7 @@ test("K1 one-intent source contract makes mode reset explicit and keeps device I
assert . match ( resultRows , /onSelect=\{\(\) => selectCandidate\(device\)\}/ ) ;
assert . doesNotMatch ( resultRows , /Переподключиться|reopen|verifyConnection/ ) ;
assert . match ( source , /onChange=\{\(event\) => setSsid\(event\.target\.value\)\}/ ) ;
assert . match ( source , /onChange=\{\(event\) => setPassword\(event\.target\.value\) \}/ ) ;
assert . match ( source , /<K1WifiPasswordField[\s\S]*?onChange=\{setPassword \}/ ) ;
assert . equal ( ( apply . match ( /await connect\(/g ) ? ? [ ] ) . length , 1 ) ;
assert . doesNotMatch (
@@ -290,9 +294,13 @@ test("K1 one-intent source contract makes mode reset explicit and keeps device I
source ,
/(?:color|background(?:-color)?):\s*(?:#[0-9a-f]{3,8}|rgba?\()/i ,
) ;
const passwordSource = readFileSync ( new URL (
"../../../plugins/xgrids-k1/frontend/src/components/K1WifiPasswordField.tsx" , import . meta . url ,
) , "utf8" ) ;
for ( const sharedControl of [ "Button" , "IconButton" , "TextField" , "ActivityIndicator" , "StatusBadge" ] ) {
assert . match ( source , new RegExp ( ` < ${ sharedControl } \\ b ` ) , sharedControl ) ;
assert . match ( source + passwordSource , new RegExp ( ` < ${ sharedControl } \\ b ` ) , sharedControl ) ;
}
assert . doesNotMatch ( passwordSource , /<(?:button|input)\b/ ) ;
assert . equal ( ( source . match ( /buttonLabel:\s*"Применить"/g ) ? ? [ ] ) . length , 3 ) ;
assert . match ( source , /устарел|stale/i ) ;
assert . match ( source , /network_outcome_unknown|safe_to_retry/i ) ;
@@ -1181,7 +1189,7 @@ function elementByProp(node, propName, expectedValue) {
return elementByProp ( node . props . children , propName , expectedValue ) ;
}
function createStatefulProvisioningHarness ( initialProps ) {
function createStatefulProvisioningHarness ( initialProps , Component = K1ProvisioningPipeline ) {
const hookSlots = [ ] ;
let currentProps = initialProps ;
let capturedTree = null ;
@@ -1296,7 +1304,7 @@ function createStatefulProvisioningHarness(initialProps) {
} ;
try {
capturedTree = K1ProvisioningPipeline ( currentProps ) ;
capturedTree = Component ( currentProps ) ;
} finally {
dispatcher . useState = originals . useState ;
dispatcher . useRef = originals . useRef ;
@@ -4669,23 +4677,11 @@ test("post-reset Scan selects the exact prior UUID locally and opens network fie
"local selection must not manufacture a backend Apply attempt" ,
) ;
const passwordField = elementByProp ( tree , "label" , "Пароль Wi‑ Fi ") ;
const passwordField = elementByProp ( tree , "p laceholder" , "Введите пароль ") ;
assert . ok ( passwordField ) ;
assert . equal ( passwordField . props . type , " password") ;
passwordField . props . onChange ( { target : { value : "test-only-password" } } ) ;
passwordField . props . onChange ( "test-only- password") ;
tree = harness . render ( props ( ) ) ;
harness . flushEffects ( ) ;
const showPassword = elementByProp ( tree , "label" , "Показать пароль" ) ;
assert . ok ( showPassword ) ;
assert . equal ( showPassword . props . disabled , false ) ;
showPassword . props . onClick ( ) ;
tree = harness . render ( props ( ) ) ;
harness . flushEffects ( ) ;
assert . equal (
elementByProp ( tree , "label" , "Пароль Wi‑ Fi" ) . props . type ,
"text" ,
) ;
assert . ok ( elementByProp ( tree , "label" , "Скрыть пароль" ) ) ;
const chooseAnother = actionByLabel ( tree , "Выбрать другое" ) ;
assert . ok ( chooseAnother ) ;
@@ -7333,7 +7329,7 @@ test("Step-2 credentials and Apply share one canonical field stack", () => {
assert . match (
form ,
/:\s*\(\s*<div className="field-stack"[\s\S]*?label="Пароль Wi‑ Fi" [\s\S]*?\{applyAction\}\s*<\/div>/ ,
/:\s*\(\s*<div className="field-stack"[\s\S]*?<K1WifiPasswordField [\s\S]*?\{applyAction\}\s*<\/div>/ ,
) ;
assert . match ( form , /disabled=\{provisioningFieldsDisabled\}/ ) ;
assert . match ( form , /value=\{connectionAttemptOwnsDraft \? "" : password\}/ ) ;
@@ -7769,3 +7765,26 @@ test("a failed Connect after completed Bluetooth search exposes recovery instead
assert . match ( markup , /K1 ответил ошибкой Bluetooth/ ) ;
assert . doesNotMatch ( markup , /Подключение не выполнено|дождитесь, пока система|private transport exception|Пароль передан/ ) ;
} ) ;
test ( "shared K1 password field reveals on demand and hides after clearing" , ( ) => {
let value = "" ;
const props = ( ) => ( { value , onChange : next => { value = next ; } , disabled : false } ) ;
const harness = createStatefulProvisioningHarness ( props ( ) , K1WifiPasswordField ) ;
try {
let tree = harness . render ( props ( ) ) ;
assert . equal ( elementByProp ( tree , "label" , "Показать пароль" ) . props . disabled , true ) ;
elementByProp ( tree , "label" , "Пароль Wi‑ Fi" ) . props . onChange ( { target : { value : "test-only-value" } } ) ;
tree = harness . render ( props ( ) ) ; harness . flushEffects ( ) ;
elementByProp ( tree , "label" , "Показать пароль" ) . props . onClick ( ) ;
tree = harness . render ( props ( ) ) ;
assert . equal ( elementByProp ( tree , "label" , "Пароль Wi‑ Fi" ) . props . type , "text" ) ;
assert . equal ( elementByProp ( tree , "label" , "Скрыть пароль" ) . props [ 'aria-pressed' ] , true ) ;
value = "" ;
tree = harness . render ( props ( ) ) ; harness . flushEffects ( ) ;
tree = harness . render ( props ( ) ) ;
assert . equal ( elementByProp ( tree , "label" , "Пароль Wi‑ Fi" ) . props . type , "password" ) ;
assert . equal ( elementByProp ( tree , "label" , "Показать пароль" ) . props . disabled , true ) ;
assert . equal ( elementByProp ( tree , "label" , "Пароль Wi‑ Fi" ) . props . autoComplete , "off" ) ;
} finally { harness . dispose ( ) ; }
} ) ;