import * as assert from 'assert' ; import { waitTimeout } from './cli' ; import * as Selectors from './selectors' ; import { keys as Keys } from './keys' ; import { expectArray , expectText , getValueFromMonaco , expectYAMLSubset } from './util' ; import { AppAndCount , blockAfter } from './repl-expect' ; export const open = async ( res ) => { await res . app . client . $ ( Selectors . SIDECAR ( res . count , res . splitIndex ) ) . then ( _ => _ . waitForDisplayed ( { timeout : waitTimeout } ) ) ; return res ; } ; /** Same as open(), but in the block proceding the given block */ export function openInBlockAfter ( res , delta = 1 ) { return open ( blockAfter ( res , delta ) ) ; } export const notOpen = async ( res ) => { await res . app . client . $ ( Selectors . SIDECAR ( res . count , res . splitIndex ) ) . then ( _ => _ . waitForDisplayed ( { timeout : waitTimeout , reverse : true } ) ) ; return res ; } ; export const openWithFailure = async ( res ) => { return res . app . client . $ ( Selectors . SIDECAR_WITH_FAILURE ( res . count , res . splitIndex ) ) . then ( _ => _ . waitForDisplayed ( { timeout : waitTimeout } ) ) . then ( ( ) => res ) ; } ; /** fully closed, not just minimized */ export const fullyClosed = async ( res ) => { return res . app . client . $ ( Selectors . SIDECAR_FULLY_CLOSED ( res . count , res . splitIndex ) ) . then ( _ => _ . waitForExist ( ) ) . then ( ( ) => res ) ; } ; /** either minimized or fully closed */ export const closed = async ( res ) => { return fullyClosed ( res ) ; } ; /** close the sidecar by ESCAPE key */ export const keyToClose = async ( res ) => { await res . app . client . keys ( Keys . ESCAPE ) ; return closed ( res ) ; } ; /** Expect the given badge to exist in the sidecar header */ export const badge = ( title , css ? , absent = false ) => async ( res ) => { let iter = 0 ; await res . app . client . waitUntil ( async ( ) => { const badges = css ? await res . app . client . $ ( `${ Selectors . SIDECAR_BADGES ( res . count , res . splitIndex ) } .${ css }` ) : await res . app . client . $ ( Selectors . SIDECAR_BADGES ( res . count , res . splitIndex ) ) ; const badgeLabels = await badges . getText ( ) ; const idx = badgeLabels . indexOf ( title ) ; if ( ++ iter > 5 ) { console . error ( `still waiting for sidebar badge title='${ title }' actualBadges=${ badgeLabels } idx=${ idx }` ) ; } return ! absent ? idx >= 0 : idx < 0 ; } , { timeout : waitTimeout } ) ; return res ; } ; export const button = ( button ) => async ( res ) => { await res . app . client . $ ( Selectors . SIDECAR_MODE_BUTTON ( res . count , button . mode , res . splitIndex ) ) . then ( _ => _ . waitForDisplayed ( { timeout : waitTimeout } ) ) ; return res ; } ; export const mode = ( expectedMode ) => async ( res ) => { await res . app . client . waitUntil ( async ( ) => { await res . app . client . $ ( `${ Selectors . SIDECAR_MODE_BUTTON_SELECTED ( res . count , expectedMode , res . splitIndex ) }` ) . then ( _ => _ . isDisplayed ( ) ) ; return true ; } , { timeout : waitTimeout } ) ; return res ; } ; export const toolbarText = ( expect ) => async ( res ) => { await expectText ( res . app , expect . text , expect . exact || false , expect . timeout ) ( Selectors . SIDECAR_TOOLBAR_TEXT ( res . count , expect . type , res . splitIndex ) ) ; return res ; } ; export const toolbarAlert = ( expect ) => async ( res ) => { await expectText ( res . app , expect . text , expect . exact ) ( Selectors . SIDECAR_ALERT ( res . count , expect . type , res . splitIndex ) ) ; return res ; } ; const show = ( expected , selector ) => async ( res ) : Promise < AppAndCount > => { await res . app . client . waitUntil ( async ( ) => { return res . app . client . $ ( selector ) . then ( elt => elt . getText ( ) ) . then ( text => text === expected ) ; } , { timeout : waitTimeout } ) ; return res ; } ; export const name = ( count , expectedName ) => show ( expectedName , Selectors . SIDECAR_TITLE ( count ) ) ; export const heroName = ( count , expectedName ) => show ( expectedName , Selectors . SIDECAR_HERO_TITLE ( count ) ) ; export const namehash = ( count , expectedNameHash ) => show ( expectedNameHash , Selectors . SIDECAR_ACTIVATION_TITLE ( count ) ) ; export const namespace = ( expectedNamespace ) => async ( res ) => show ( expectedNamespace , Selectors . SIDECAR_PACKAGE_NAME_TITLE ( res . count ) ) ( res ) ; export const kind = ( expectedKind ) => async ( res ) => show ( expectedKind , Selectors . SIDECAR_KIND ( res . count , res . splitIndex ) ) ( res ) ; export const modes = ( expected ) => async ( res ) => Promise . all ( expected . map ( async ( _ ) => { await res . app . client . waitUntil ( async ( ) => { const actualModeSelector = `${ Selectors . SIDECAR_MODE_BUTTON ( res . count , _ . mode , res . splitIndex ) }` ; const actualMode = await res . app . client . $ ( actualModeSelector ) ; await actualMode . waitForExist ( ) ; if ( _ . label && ( await actualMode . isDisplayed ( ) ) ) { const actualLabel = await actualMode . getText ( ) ; return actualLabel . toLowerCase ( ) === _ . label . toLowerCase ( ) ; } else { return true ; } } , { timeout : waitTimeout } ) ; } ) ) . then ( ( ) => res ) ; export const defaultMode = ( expected ) => async ( res ) => { await res . app . client . waitUntil ( async ( ) => { const actualModeSelector = `${ Selectors . SIDECAR_MODE_BUTTON_SELECTED ( res . count , expected . mode , res . splitIndex ) }` ; const actualMode = await res . app . client . $ ( actualModeSelector ) ; await actualMode . waitForDisplayed ( ) ; if ( expected . label ) { const actualLabel = await actualMode . getText ( ) ; return actualLabel . toLowerCase ( ) === expected . label . toLowerCase ( ) ; } else { return true ; } } , { timeout : waitTimeout } ) ; return res ; } ; export const textPlainContent = ( content ) => async ( res ) => { await expectText ( res . app , content ) ( Selectors . SIDECAR_CUSTOM_CONTENT ( res . count , res . splitIndex ) ) ; return res ; } ; export const textPlainContentFromMonaco = ( expectedText , exact = true ) => async ( res ) => { let idx = 0 ; await res . app . client . waitUntil ( async ( ) => { const actualText = await getValueFromMonaco ( res ) ; if ( ++ idx > 5 ) { console . error ( `still waiting for plain text from monaco actualText=${ actualText } expectedText=${ expectedText }` ) ; } if ( exact ) { return actualText === expectedText ; } else { return actualText . indexOf ( expectedText ) >= 0 ; } } , { timeout : waitTimeout } ) ; return res ; } ; export async function tableContent ( res , nRows , nCells ) { const rows = await res . app . client . $$ ( `${ Selectors . SIDECAR_CUSTOM_CONTENT } tr` ) ; assert . strictEqual ( nRows , rows . length , 'nRows must match' ) ; const cells = await res . app . client . $$ ( `${ Selectors . SIDECAR_CUSTOM_CONTENT } td` ) ; assert . strictEqual ( nCells , cells . length , 'nCells must match' ) ; } export const yaml = ( content ) => async ( res ) => { await res . app . client . waitUntil ( async ( ) => { const ok = await getValueFromMonaco ( res ) . then ( expectYAMLSubset ( content , false ) ) ; return ok ; } , { timeout : waitTimeout } ) ; return res ; } ; export async function popupTitle ( res , expectedTitle ) { return res . app . client . waitUntil ( async ( ) => { const actualTitle = await res . app . client . $ ( Selectors . SIDECAR_POPUP_HERO_TITLE ( res . count , res . splitIndex ) ) . then ( _ => _ . getText ( ) ) ; return actualTitle === expectedTitle ; } , { timeout : waitTimeout } ) ; } /** expect a form in the sidecar content */ export function form ( form , idPrefix = 'kui-form' ) { return async ( res ) => { await Promise . all ( Object . keys ( form ) . map ( key => { return res . app . client . waitUntil ( async ( ) => { const expectedValue = form [ key ] ; const actualValue = await res . app . client . $ ( `${ Selectors . SIDECAR_TAB_CONTENT } #${ idPrefix }-${ key }` ) . then ( _ => _ . getValue ( ) ) ; return actualValue === expectedValue ; } , { timeout : waitTimeout } ) ; } ) ) ; return res ; } ; } export const showing = ( expectedName , expectedActivationId ? , expectSubstringMatchOnName ? , expectedPackageName ? , expectType ? , waitThisLong ? , which ? , clickable ? ) => async ( res ) : Promise < AppAndCount > => { await res . app . client . waitUntil ( async ( ) => { const sidecarSelector = `${ Selectors . SIDECAR ( res . count , res . splitIndex ) }${ ! expectType ? '' : '.entity-is-' + expectType }` ; await res . app . client . $ ( sidecarSelector ) . then ( _ => _ . waitForDisplayed ( { timeout : waitThisLong || waitTimeout } ) ) ; if ( ! which ) { which = ( await res . app . client . $ ( sidecarSelector ) . then ( _ => _ . getAttribute ( 'data-view' ) ) ) as 'leftnav' | 'topnav' ; } const titleSelector = which === 'topnav' ? Selectors . SIDECAR_TITLE ( res . count , res . splitIndex , clickable ) : Selectors . SIDECAR_LEFTNAV_TITLE ( res . count , res . splitIndex ) ; return res . app . client . $ ( titleSelector ) . then ( _ => _ . getText ( ) ) . then ( name => { const nameMatches = expectSubstringMatchOnName ? name . indexOf ( expectedName ) >= 0 || expectedName . indexOf ( name ) >= 0 : name === expectedName ; if ( nameMatches ) { if ( expectedPackageName ) { return res . app . client . $ ( Selectors . SIDECAR_PACKAGE_NAME_TITLE ( res . count , res . splitIndex ) ) . then ( _ => _ . getText ( ) ) . then ( name => expectSubstringMatchOnName ? name . search ( new RegExp ( expectedPackageName , 'i' ) ) >= 0 : name . toLowerCase ( ) === expectedPackageName . toLowerCase ( ) ) ; } else { return true ; } } } ) ; } , { timeout : waitThisLong || waitTimeout , timeoutMsg : `expect action name ${ expectedName } in sidecar substringOk? ${ expectSubstringMatchOnName }` } ) ; if ( expectedActivationId ) { await res . app . client . waitUntil ( async ( ) => { try { const actualId = await res . app . client . $ ( Selectors . SIDECAR_ACTIVATION_TITLE ( res . count , res . splitIndex ) ) . then ( _ => _ . getText ( ) ) ; if ( actualId === expectedActivationId ) { return true ; } else { console . error ( `still waiting for nameHash; currently "${ actualId }"; expecting "${ expectedActivationId }"` ) ; } } catch ( err ) { console . error ( `error waiting for nameHash ${ err . message }` , err ) ; } } , { timeout : waitTimeout , timeoutMsg : `expect activation id ${ expectedActivationId } in sidecar` } ) ; } return res ; } ; export const showingNotClickable = ( expectedName , expectedPackageName ? ) => showing ( expectedName , undefined , undefined , expectedPackageName , undefined , undefined , undefined , false ) ; export const showingTopNav = ( expectedName ) => showing ( expectedName , undefined , undefined , undefined , undefined , undefined , 'topnav' ) ; export const showingLeftNav = ( expectedName ) => showing ( expectedName , undefined , undefined , undefined , undefined , undefined , 'leftnav' ) ; export function breadcrumbs ( breadcrumbs ) { return async ( res ) => { const elts = await res . app . client . $$ ( Selectors . SIDECAR_BREADCRUMBS ( res . count , res . splitIndex ) ) ; await Promise . all ( elts . map ( async ( elt ) => { await elt . waitForDisplayed ( ) ; return elt . getText ( ) ; } ) ) . then ( expectArray ( breadcrumbs ) ) ; return res ; } ; } /** Expect DescriptionList content in the current tab */ export const descriptionList = ( content ) => async ( res ) => { const container = res . splitIndex !== undefined ? `${ Selectors . PROMPT_BLOCK_N_FOR_SPLIT ( res . count , res . splitIndex ) } .kui--tab-content:not([hidden])` : `${ Selectors . PROMPT_BLOCK_N ( res . count ) } .kui--tab-content:not([hidden])` ; for ( const term in content ) { let idx = 0 ; await res . app . client . waitUntil ( async ( ) => { const expectedDescription = content [ term ] . toString ( ) ; const actualDescription = await res . app . client . $ ( `${ container } ${ Selectors . DLIST_DESCRIPTION_FOR ( term ) }` ) . then ( _ => _ . getText ( ) ) ; if ( actualDescription !== expectedDescription ) { if ( ++ idx > 5 ) { console . error ( `Still waiting for expectedDescription=${ expectedDescription } actualDescription=${ actualDescription } ` ) ; } return false ; } else { return true ; } } , { timeout : waitTimeout } ) ; } return res ; } ;