From 1fc7268df2635cb9927c3d18a26ed2fabe21bb3d Mon Sep 17 00:00:00 2001 From: William Wong Date: Wed, 3 Jun 2020 10:02:12 -0700 Subject: [PATCH 1/2] Fix ENTER/SPACEBAR on card with tapAction --- .dockerignore | 1 + Dockerfile-testharness2 | 3 +- ...act-to-click-enter-and-spacebar-1-snap.png | Bin 0 -> 38505 bytes __tests__/html/__jest__/WebChatEnvironment.js | 2 +- __tests__/html/adaptiveCards.tapAction.html | 113 ++++++++++++++++++ __tests__/html/adaptiveCards.tapAction.js | 8 ++ __tests__/setup/NUnitTestReporter.js | 8 +- package.json | 2 +- .../Attachment/AdaptiveCardRenderer.js | 69 ++++++++--- packages/testharness/src/index.js | 27 ++++- .../testharness/src/pageObjects/runHook.js | 1 + .../src/token/fetchDirectLineToken.js | 4 +- .../utils/createRunHookActivityMiddleware.js | 10 +- __tests__/html/serve.json => serve-test.json | 1 - 14 files changed, 210 insertions(+), 39 deletions(-) create mode 100644 __tests__/__image_snapshots__/html/adaptive-cards-tap-action-js-adaptive-cards-with-tap-action-prop-should-react-to-click-enter-and-spacebar-1-snap.png create mode 100644 __tests__/html/adaptiveCards.tapAction.html create mode 100644 __tests__/html/adaptiveCards.tapAction.js rename __tests__/html/serve.json => serve-test.json (97%) diff --git a/.dockerignore b/.dockerignore index 9a97864a16..527d2f98e2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,4 @@ !/packages/bundle/dist !/packages/playground/build !/packages/testharness/dist +!/serve-test.json diff --git a/Dockerfile-testharness2 b/Dockerfile-testharness2 index 5a5d6e8cbf..bbd9b780f9 100644 --- a/Dockerfile-testharness2 +++ b/Dockerfile-testharness2 @@ -8,8 +8,9 @@ ENV PORT=80 EXPOSE 80 RUN npm install serve@11.3.0 -g WORKDIR /web/ -ENTRYPOINT ["npx", "--no-install", "serve", "-p", "80", "/web/__tests__/html/"] +ENTRYPOINT ["npx", "--no-install", "serve", "-c", "serve-test.json", "-p", "80", "/web/"] +ADD serve-test.json /web/ ADD __tests__/html/ /web/__tests__/html/ ADD packages/bundle/dist/webchat-es5.js /web/packages/bundle/dist/ ADD packages/testharness/dist/testharness.js /web/packages/testharness/dist/ diff --git a/__tests__/__image_snapshots__/html/adaptive-cards-tap-action-js-adaptive-cards-with-tap-action-prop-should-react-to-click-enter-and-spacebar-1-snap.png b/__tests__/__image_snapshots__/html/adaptive-cards-tap-action-js-adaptive-cards-with-tap-action-prop-should-react-to-click-enter-and-spacebar-1-snap.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9d3e015ecc7c1c0d8af1ad53f47c56dd5b266e GIT binary patch literal 38505 zcmeFZcOaL4-#7f#q9Q7pMOrEeA+jSh%!s0>Wbf>)6fIP;XJm)U-jz^fuaJ?EP4?z~ z9i8WOJ=b$T&v{?h_1w>&_xVrf58rWoj?d@)ey#WMSV=*aY8%rw5{X20;rzMFBodhc ziL}9;Vheuqo~b7u|BzW-mX#!>R_`4mk@k}=oI9&(A2!_h>K4}Z%xC`&ic@X#y?Hr7XDVH~2Exvy<<^LLosBvA;Qu-m2PJoITs% zuN~;kd~2ffcS`SB=T-hNVg1$**RK6(Quj_~=ij6D*8R(uvJ|fGV_nqii@r-g>U*d5 zmruAF88uE1EzSNuwr**g#+_=MXR34D;JY@>+Ct3I{oKI8!Lp1uu7-x){hOt{?x%3B zjOurf{>=HH5azB`DB%>Doe{O)!ot9QaqHISFJ6mfWo~9?|1<6J@uO#8ld6d5t(n2H z6sMV^luU2TJPb6b?_NLgA|S4a?Pul3d$noW(@o~yAya8_Bg|GsnlT&lcp@CPNlG@B z2M0fYxuHhP$*D+-nx5;lY51N!wMC*oS`%wH_co-(<}tZ0ZFP1YXRYnX<4@huoA>&) z(ZnGE`ngeMk33o5vcSdtd-pQU>%|-$-gBuv>!wb_%-E87%a7jM$Hc`4+pf4=SKAUQ zP!hz`J)ESFo^4)~_b^vxv$amqQ>l0rw`acmOcs`jg<)#jWql+Z^O#i0$cz*z8>2)l zB&en|vp<$>{QP-%e2;l2rFvRY;LUi2PY<>ZAD(}6!Dz6wT*^L2L(77DW<15yLhp#` zm9rzw!^{_#=Z1BoKarBvlN%i8Q*U(T**p)77n_?`cN&u+-;toJRh+uEW9vOBuSV0= z)*7?odp~|8n5#yOhxV3NdEH6XR(Cq>;4myC>X@Kw$T#dPtz0Q;r_dojKF)3bE|1D4 zF;RJ5r9JES7=J~@{f_)wZG5wflf6b0NpIy$^}C9OCv#P7_}^;8imm-3|1;+~-qB<` zKTh@S8@FqL;|KP`i8iWNI?RmoZHK29>>18nPD#(X8ou7=H_UVV_+_aB2cpMy+~ND}yn@97_p4V4%Xhv|%rZ1K{>?;oBMSzj4z8JX-IHa6<{vOE#^ za@UV+>eL%5+ESgJ!?r& zGWSY2YSTU*dxc|`+^je&EbMztO9<2SSY@S(@6gv5-M?+~i?B>B7RhSEuDR+p!or%O zircm~wcv_|UF(gQZ94@51D4j^~wS`s3KK=aFgE!WI&uKYGhcW`>4i zI|De4xI4!5#Z?qPci)`t%kz6r?>u+n8FTy`gF^Uar<58|a<0NRo}<;_!ykIf5-W=r zZg>2m9B%sfJ-9Yqf6PH6g^3A27mYk9+vu17Vb@9R)ck_5y|WKSelE^s>=SOJAILBq zo(mUEUSl}Sp3H83=S^Gl$s65W>uTDKHW%bn+jlc*%&!RVp-o_;W8BKCm+;GWuy#yG z=Zl zt5-U$Iq*j{G>n)ft0jBt>c%dW?cMph$Oo5F8OnEo>cOSJ#{LoGN{>-`X=QO0OUrxo zT1xFV)Z(^i+^7!s&?#@6EBbRk&s*5GQQPgp<2>yR8=JD07ZXj3mxJi{BQ^V|nEUt)uXNwc9C#Vpp7U!vYh-(%>7G5q%u=|q zTRW2jmu?Hp?H?~^I6kk@St7;RRVqEkX254e-Tk|&z4DG;QsGJn(`>1o-GtqWz0D0~ z=FEto)VhJU6TNn#L)_p0 z&zIfVX*3FvY9-%)2=C>VFm*Fa&AUM=Dl%G3(MT*Wc3Ey$zs15boYi$n-h1iD_U!pv zzAV|5R#qz6>#nAT4RMpphXvGAbUtsI4Qg#mN^7kOZDK3V_o~EOX1A6|xv=bto|7Ee z9&I(yc$!Ig3mMt)Tt}{g^ur~YoqL^~2BQ-fmXpi3G-{b^ge(ajlyZsT&8n=DH*F8* z9X{Q8LAjBGzE`Yqq-lq*OiYn&=u(0Cvw)@F)n2E!m?q|XiJF);`K7#-D{O525IZM? z?jx*Z*W8pG$n+eACh&7dUSeR3e1G*NnO>cgW)Tr#J2kEm$}O{(xsF{J+e)=Jp}N@h z#+VB|eR995TBqxKb=8DQCPg}(8)bir8WyLAvwWECCN7QTJJ=_%ciVL(F6UjM&osGI zesE%MQLclEXh7MeTS{H_Gme=9x|9aJQ&CwB4Ao^*!y~`4jC94UH~sF-Dtqm{oZ0V6 zcB9Mn*hw|t{;B@V77mVNm&aPy-v;QuX=rkhww)KU3$z;GQK!xHGSydi5==Vw(_sf= z%@v*eyH>_sA-3}tR0(MfXFVFJD^ygPra%60F!GsRQ=Y0Vi(-Anb3Vdpe2v{Zc6{{H zptX@AyMX$>k&72EbA1cx9e?TcKC{r}LvCIY*H2bARi_Blu2|#qkJ^mujLf@iZ3eQg z-fdM^iYg-8Cz7y3>T3P=W`oAc-nG@HUm?#ZXBE6BdpVi67j$_g%LGtz@CC#cx*WXJ zcDc*-{d+W;h+?UPD{49?+eb9xqa|H*@+_ssOvT?)hnbo-350$9er^*by3s}tV5F|0^Sy4;m0D%xac)hqa;L+35EUvz@# zyJ4f*O$|m(TF-e#$4x@R!yUI?y=qY8da+{cl0!`QO`D(Z-t^5K9$ICf9RAjsmnmd@ z%C$g4+a+6}^Jz?sGrZgy-O=b4;9VYza_HX=E|5&B`+|Ok51T?6Mqds+mciV;;%W=B6V_PL1U6Pxe-d=MqE_H3cG7jEL)ysW-?W{}p9oJYy476%I zOw2FoMl^Y!ZPEWonvHT^FLaD*%TS)E;q&1adsM45Thwb_e5KN?Lu1TAP%we4CDG6E zz!vgkw`X_b`|iwcwvJbcZ|o}5e1GDFf9x7+AlF;tmiBChEc3K2f3OVSTGArhIF@SM z8c7sXSGdxtw%8P;CS6?3aQzOhCO(q!Z@O`#Y3y|8EsNsSQ+MAuIu|X< zP_^yY*Jx-nIj7bYwR=}%??8WS(Uy^zmgI8#2`!tesW!$8{1wgxod!R+7g~xN$0#V2 zvR|Ve6egFPk5_4b@#;+k>y8~p2J;izPOZ%;P3>Ff$5cEDu5j3_Q!zwUXZIC|+bM`@ zmE}il+tw%`+`G7OcrMGlOQgO1I@7GF?UeY|hcxT*eQvw9u|42E*hNm@=R*W!Uf^Q? z`(N{H>wZcUY!4X!Lgy_ndH(S`9iVYb*1vfB^Rs7Xx3itw_>CchMsg+4kNArmYU0l+ zZpoBIJ*0`gcZX7gf^Dsmzm;L8qoFTXByeDA#nNT%-Fa&K{OzlMy#87TLq{k@slUpXr}Q+Qt3ESIBsbk1Y33wp zISw7xa$B`|`SN9s>#7i`%XykAT-Z(zFI*W`FYfss%zNnY;a|PIQhItvNYc{MgVsVP zujh~wx(>he_kWm{W^QHv0U!EUkJ><8UA?}(KF4|SREkFC?TS~&a&mK<@_l4t$o6w{ z(~!u?$*$mjX}nm;^0VIbx+L_X<8&iC4gflsw!{uSEOMYM>g+MLjw? zdi2;aHeun=<`m7|o}T&w<`WNSdg$+T`zR> zUs$jgvK_r@e6{5A$&)7;D7REpR@Mz!lV17z{~8^oyvg+Y>-X=6goHwdhmB61I(78u z(VK&{uf3C0DA+XamrCsoJbB}GL!A820tY`1_0;F#;quvL9V8ou5<#)+Dk@Trj(J0t z*RStYPt)4`v7@7dHmPjlGA9?8xspeCSlD1&CdcyJ*v4)w%U&VtM`A8ZBqIq{QAgTv z1+T(F(T+TugS@glv}e7Jod3(=?ZN=aJMSI;9&o zIDf4?`jDONW}q(iA8W*a=_~wCFPNk-0FlNHPO<8IdH7PT0Uy=ziQIvRg9i?5aG#m6 z=3}CAnjd%Rwq>GX;(PSx&mWD3Z1XN0l3(dHV#)mGOEW|Ej*enVg{JLUy5C+No;?Zi zf>p03VpU>RmA9PyeopDJb~aGaJaI?emXXh+@mDTS1$uRcJK1q$sv{$gwbDpRjFE+#Y&*KhR3! zw8FC4k(LXWF7Z}fI)9$TO_hJW$T|3%A3HWV^XS;vPODsXCfccUA z``yoaY-wusaao?*NlW_xJJ;3K^{r-hb&u)0Ex1yV12}m{Pn>u=YlTvk-hbM(?VOw( z<<6Zu-@JK)vR8w9=+N)4ej-U9HTZi7|I9aV@DF%E@{q?bzoYsFQ$oEbMJ>5+V1NUEkKJ|Uz<~p_ z(#o&YwH%}uTWehPG_tUa6{u}{@KapFare73gUabsl2TIgBl>sl9Ce=x?OG`_VYIWe z>-TkAiNQvgnr+eMaKDRN(y&q)$i>0rE#t5{+rruDlgHP$uxHO6{v}x`ZXyScD1@EI zb)-Zx^6CWz@GwyB6>|XWzj?hrXCBxsz=qoxgD5 zeNG{k74>n~?%iaWfg;We7Aj7*6P@z%@>J!%tOLVM$#IhdeSLSVh4$UMcQ3Qe!fsW{ zlQLI-m0clBBCVx&V!}M6`Mr)Ts;$A~=?uQbKy`c{A)8^z9lxNcvM$cXAa{w7V59!Ee5UgG#XHSPjq?) z93kWUqVuJ$ZYN&y`+IN+x}zNA!lRrbP#txuwZ9$KTkdJMOW%w}e7jC%L( z-P!iqmqd{&f25XtSWqzN?b{QMz?w^wb8~T5lGXk;*rM=oV(muTvujM2P#4JL$cz)e zem!5`(9oJ|#s2#B>mRMH!M`7RdHKD1^#$kryIC4D_e~NyPS4jD2Q%AhpD(ShtR%dB z+lM_Fhs|i%_xty017?kvM0E(>yq)fy>#E~z9i1~)zbTI$J0=${B>^wjg{@0!S( z08Y&XY|mVaUmLb=-HMg)!ftQ4I)k%8v32XO+SgLE0ecu3FW`fdzAR1;I4qB4pK)H`HZPd;EM5K;tRL|SU%oY6-)gXyZEn1y z5~W7Zc8~J4YZuO+r{GX~`!46F*M$ulkIKJ4*t+{_p(DR>^V`?B70;OXp8$NJB+BW0 zn|=KF@vYVmx+gTVD1onzC`QQH+Y15}@o}oCs-C-ix!z@CS3`pzIw^3HlJSa&h)CG| z`x`W}&EzdC-WlcrnYL${0syd_laZ;T&Z7;(=<6x+i?AXw$TK>L;CjK2}$A*BbnMP6L!UQevySuvwm{sV=kM{s<1$lXSwR)LHJNy$t z|0|69-|JrnWayl#s;U{*yyp($-3DMX4I;-p#H6 z?DvY*b%9J;8J*-#*)v8xUDx>zJ3(P#m8)0J8yX&qjg5uWI&D2zOXe=>G)F*qTIsX# z4LkSk^VUimi18J>J=s%gkg0L`^5v`PdQ@nZr&Ci?iT;KYIN7Xe&c7`70x;!jA+LV5 z#oCGkPKB?xH&tR{;$CsrFx2={_J3{yAO>^al1!P+(BK>z8p1gtcXD#dGV8c_`}P5@ zf2qG*BiNt z77pOs14B-=>PNl^4>zsL+p%LuTsdfp$0w2m*3+@DlTR_Gu6uBhSY0tOu`qGBh|ixT z_wLc?nY#$=4YfjWgGkY0Wwd9;3#KI?i-sslr5^=m0?RQME>y zVP~v7ZO7VzAG%r*C{lzE+uNi)%NyMW9fJS}9r2QS4Po&57h zLYa1HZtN0}+57kJfBg6n)iM$+XnBBC=s0^oOf2HZkE@-|)ACQ-d%%(&?L4^9^OQ@8 z76uV}oP4OKx3{;UtEA)xApebx?rTHwk&m7{G3qJ2Yd-aG70CP9-*ft3WXAtV)p%N5 zReh8Dd0?Qdjg5^}mMq02!@JDP(vFUODQZjZ)Sr9Yt1Bx@(0ph5+n^F~0Y(6S*8zK> zfE}#r$<78R+N#g?KpMEP-zb0U*IBRscZ&WWzliRn3r;;76W8Ixr9HYH_wSR4^7x?X zKk|d5)(wteS?A83Ydka2n5Y7<)tq|6*wP`=b?I1E)~P#dg1MHxG9KFGk}Co)STg>v zPgUDl3p7w#QsVLE%^{G_5 zx-B-Pxk>{A6}A^Z6Tmyy4q2lQLJu>y6eerSHm{Lob@{@PRv?M4V`*ijv$nE$J>S;b zvbU@bfI825=<}0397baUU%s5%uyG?Q#HKAXJ=^qZc*n zkyEE$qG18we~CKlu~6f-*3jKMzc>)tfO-k!1&Dx3_0wbx;syxIiEAJFB9_Oni%y5S zE&RE~$K+kw6_#Z)q9!6LYH4fx8x1R&e|^4qT@)1ZM|=A;{!~L%PsPH{P9F#`Gp-!< zVWvS*++q=51$3qd?E_abk-swGIxh^(A(lK*iq}`o(Tq)%8G#{gH^03`V33RqzUDOT8WdRUc1dMgK;rWk zFP;h?1=8;CDSdkM$>(5ReL0(n)^so6A;<}&AOUlh^=a|-5+LM--=XFU_?FiIghaFL zaCW|jo$(9Qa(oQ9b_$S0uR6?->1m<1u=nz)2esIK(D{*;wB5|imE^3>AA@*w?5C>) zzExK0pe_{5wHedW(guwU)QGQ#-N?7K?624Z`Vz!_YXiUs0P@|bz6(28#lGXUq=eUt z_~72|?vHM3)2usKM7};}lVT8eEif$B_%Ja)+FHWpws`4?e8@SJo8sk;iG?b2SDh?v zAWK~8=koG+va|?Khozx-LeR)AUNsG$?s6E|ch|~_QOwysJ@fU+qN1WZy1Gpvu4rCI zT3Mk|0MvcZtqdSPc}YYB8=eGaSTLJZ&`|MjS%79u=vZ65We7N%n3QyYpFgwtL!|T6 zR!9_m>uVG1gY~gbOLd(WetCiaOr!Im|6ICyl>zk_^>7+D9Ng^ewQIpco>SPF_wV0l z0M2xp8zt)oyFnA%&B$n&WC!hrlJV3gcigxh)N}}E6S*nq(QLitzWSf;Z{9>s&THN& zLU-co&28z+nGFeU>uVy@-+6JKZ{NO6VmNh&0vv%yo`Z{PU}mU6Z`lAZ$}sB)fgZvO zRi-*pyheL%irCp8sfR>Fer8Z(<<6f!f3x(-o=uxK|C*Sn0q8i&!Jz}pPB*cPM*eGP z=o|4OXBQWc97+Ozwz|GgPw(|&b-g*&_ig^C-Mke5o|gTu&CbrwgUu<-+v!ghOf<IU=2`!5x=(Z*TX6VjTi~B*^D`Ni~z#09Rf`XzO5co6) z0Vzj+y!U|rRhMO|iOwbHH1}3|mKDf>Y~z;hu`yG}-Mcw!j5aVuX&1Z3m7AHFk>WZd z>j1lh#NEV3np1dJGrbS%s$RKbIr@VKEbV&$D^@*f&7V-RhU#Lxj@hFPmI8<~p1Sks zSQIoN@4!HMs5&;yhHvM`ZM#5TgTV_zIm+P~{C0VMB5ltdZ=3FqWY9LMaP|dlhG{|JcGQS1ziqWp(&=dR zU=c728yf!1P>YUBYyjf3poXNQ60I$ii+{ksDvUU+zcX93Vz5cD!w99oac1zA@@iVa z)RUnq$Hl4s`i87sRdltdPeVrb6dGXkqIo8@Nk%9n0yT#2Q_gc3PLY@S883~(uv?HHhX`>_5t_Pl;A)9By3-vFxxx}NZUshJWr$i`zQ{#Fve+!>E({!zR zwP3!}i71gnLx!itG_PL$3PswX*IR&Ss&#cQ)U{pw!D;xCBJxq4ee@$;nj2%Vtxo`E zn7!1>h>T=~)Qq!TpLB%-m4xEwjzQoWfD<|Oi})Ko>|K+eId!U@=xHFH-$Mm_0W8TN z=Z$OHNlR}QU!BuR;yq;(Kgy-&MUl7UB+dhar(_yu;u(CK!0ychqR`>Xm&-nDR zG`Ce_+%nU=Lm3aW(opF=A+4nkl??z;x(l6qZ{8)As$EhPgMaLZ2uDBjSQ z5O@$1bI`}fC$p`t)>iBUpxi!ac5knxdv*B z0cZ)0MZRJCwr$Xc(bwuzGzG9>%GOtE)`JQYMIV7nfv|m#bFjDnnVw!tQ^w|lD?erO zgImaMTn^BzzrWvlsJ=8hkDtkV=wdS4Gj++bWEOV_N_=-Ool`N&a(6{7CFpH?wz)v4 z88^eibmY2Ryh6Br&trBb)i}U;9v&XR-g;;eaSGv%HCjs@Xebnvlzhwrn|~C$iMtzq zz4hhMPNK@*F5QNf;1L?ijH^Yxd9PPRXw4IgM8@HLQ@cgZ$KTvG9UUFZ4x1ZP z9lkt46V4@kKKGsmG?|cz0%#LTI#hsb1@=6UzC=M=_0gLMl^HE~La+A))h~1{$Tnvz zx=E-O5v3zlk>Zh@npuB-d9mL8^?5TGH%iEkTeoh-MR?`s3!goE_DgB$WTT2=aPvMP z>!WBED3y zzP`Rc5Uo5s$f-fuw?b`7ps3Anie7_RIL@IgYbQttr9Kq-102 z_;M7&6=ZRje&pG3;6f-_#lj$OhI*V;fzfjQX%BAMb6H zFF$zjU`%u9fcV-ZHF(t0N1MlFGFK`{Jmtpn(x(n-F*B$2-tQ#g!IUm*)ql z-4-^2?dA;x4R+vfu4b7qRt9jEl$U# z&WhGy4^#+rIhWvv1g?1e^eL}5mquH)*DrnXWybAvCvL*d0kaMzbSMB$EtlCVYN^-1 zX_^=6DxZmw@$NBqTV@9FEM|Z_MacR1?2X*BNybJ-KQavcT5qsZ&6d(@KaY&`_4TC& zryK1mjszGb8{Q{a7BQbcQB+ASzH-wsA~LcD1xwd4;`#HB?dHYakdq0&>cN8tf4;Ft z{uxcLsZUntTAPU%pDdvkug$YDR$0Z7iwBo2SedG%GRsFj1AH!TYVv>noW|^D&aG_* zuxJq0elD2N1{fdgo3&CsTVKp z0hQy;m&^mu;LqvDu%mn`g#`*7qFZ zRV_=FTNE>3(@=t@2}48&x&gd}$)M+HUb~|oLr>#xC4VXDK0{cEM*oqg{7a|ef3gYw zb8F*Yy`bp?*(%5%ME~K{MJ#AY%<#I#KN!vw*O7Yn=tR4iu2svCKDixXZ+_!L$n0b`3_u42|Q`F4_y@ z6MtX{Rsk~+wp->|T{q~1@C#``d_hKn0q0TM;}(H*bU+-eM}O?ZRlvmpY<+x<5iUaUE2?`1-sj7bI`{uW}SmUPP>?{Ja0V>e$y?eg{`;4~+5Ed9}3*;DxCxf$&AXX49 zb&(^5SliRn^ZCbn9h9Ry!$Rna0H+ez7=}$rdjR$c2+oOKMgoo63jmG%x0Qn8W^L42 zI`d+h=G4*+OZ3GHn}uyh_X`WR^QF9f`wSHz_~h)^=;%VF_L?Nr$lToAy`qk<028>; z8AzyC*mbwo*H+(NeSaUC#g-j=zk+j|S5!35$||0&7DlHz<-G8R{N%_~eHO0)B1DLsL4A3WGJ<0uM)1BfUPWZ7r$na`QVEe7pb zoVx&B4-V1b{flUS(vKi za#&xTKjScU$Ze@1^3l_$glio)M|MK1AP9C}r3x71;ayJBV?xv-E^Nd-b z+9Vg%jl&&oK&Mb83bhJ|iCm4;KRqH{Sg!xUBf2Of<9Qc1HC;EtzGrKHle#v)=){lr zF}wEeHOcx8H=mZCp1vQOEzVHeW!8VgQC(eKn=Eq(-P@u-$U@_)LIo7bUKzKf2FJ;V z@LgaObEwO>;@t%U;^pZLHHM~fG$%)bY`zq2eo?fCq= zeHiVYJ;&gARp6RVtns8a+!i%JdxR55==t)R`L>)`vlCd5I73B|$p@{DpcX&#Y@QO% z_N!NfuSbA^MU9kz_z1@*uU@@!99c&rCNPG2>h)Vcb1VxMe}~37r0Z2dO|t|~h8Fh; zOTP$Yz}a?EQ&STfz(w@ST$FKbw^e@pGOn>&U}E@xrsCt-He&^c}~4 z|K1`2xKe03{ZH~k2>XPDD9>^H_=f%b{Qkqk!$R}Y*RC<*e>Pcl^<(s(+cF1TYKs?2 zxri@<9S%`@dctiz6qT&igb{TreE>$dI~33-PoE|xBuGFo1m0bG?CXnP#&_n)dNWBE zyRMQLL>>9y8Swk(J51{lhY$LrrL}b*Zo4kX6P3r8nh|1 zB7d5yVX)ew$nS0>8v|tN^Z|m#oQTQEVfYyBVyVx}+3L#1vYFGd*Tlkto4_lP>nrTI z*_%w;GH&&KeW6$RbKm(gzvikcDx^RN7K=|x`Cw{dGMti+QWsZ_k`YH8zU|*IJlYp2 zAu*Askmo9HQ%S~2iO|!gR8lqL&cv=v z9(N1o{*^~n;hirRFJ`I){YBO9qOCoFY zv!kPG7`c#)1RpOpBx10yaXtE{zrS}|cSRXPyR<0f3#GffBmd@3&^4m>KvKj(r(s}t zgl|V^NZ5b`&?hK7jAP5C8AH6i-sIfrK(H`woifTbVCr=Ar;}O*UxCC*yVlq2epiQU zPG~E1nlF>BP5QcVgNS-%o{{9c`ji|>dI~{naP(&YE1FkO#p$8IaU0a`cU_x~oJKPP zoghyrVF0^|g(D~jzz+m8jb(eWKEJ-kIz3QhZXH^*(6b$42NwSm&^Goquh~yQQqj^d z2LJ|8M|JiM+D9>aeyru-LV}+U4jpV_vj)gaFWJtx@Ri zK|u_-LuJt0{!C8Z0tJ8I_n;o zN-g>d`K5ppw;)#$eEs`(Ihkh+b%U!duYg1BhhhWm(K(4fdP>jr+pc(dAE-l;UE#8+ z_(voaMhfjT9|goIkIyGouXC}plXG#U9Wnoia{}A=cO_Tx9Vl>m)6k+Tkr!C(m~d_B zn>`(fHa_JgzH%=kBO}1<2@Pjb?x|j7ot5ujUJAc^1})E>ZuIQHzyNXnax8oQ%+Krh ze0j{-^y-NIFQ*6^$;RZ;4MK1#5VZi8y_RolnnF#Ev7X`^PpK`Dq*Hv!m?V4m5kht6 zR{s&f`)}ap6FUrWTCh|h>70^}%8@{lF4QLHIH5DiVr^%~&c#(T6Df=ApB8Fn)f(di zgS}5TY9Rf!YNg2bfTrpa5k&la@xSzeRBI}caLV4J2-8a60&;xt@F9QR6ok5-zpB4W zOeM00E#fwr#tOL>ZXtOZ10;lQ%9}Tk{d6!#@yAs+`sBJ2cg*p@w*<%mfz% zmu*-9X@&dZrIuXU)fGv^3T?+UU>PU^Lz3K9N3?O1^>AlMU&_l7Ez;gX$xurhibP~p zQfqk>5Yu;@@vAu&Y~Wn|NSY952H74GK?>6?w#?R4n0MrD{&#bSmNaeh z?ojih*LcN=>p9Q0SBKRJa}DqhN+=52rl^Dj3KR@N@kD)r?hO62{bwkV){Ac4*ak8O zt^TBTksJ_1&?((*5HV*{W6%PipKSVwYJ;YMWaP1vCx0UyL&DX zgviAu8{a^tghUEH$lWlA25);F(hfEXxN}Pc`%Lk^_>IWZp}7l{Tu9n z6aZby27MBRbp-TxLvOUS4eI0j96b&2&gYHK-pEFuqZxb|wLIyEcZ~SMjO||BS zJ6oB&SLW`^h6p*?@3h-^F0=hRcS=7mo zeK)~-Kj-)K*|RqvK73G1a|UrCVl%LAXr+1NYrcN%#%bJDYln1056{e4cGoG3ZV6y% z?2tPU?tpYP3)TQ|Cgo7%lejcC+D7(7YbaDN@tm4EHAc=_JDLQ(TP&=V3qX{9%fKY<3 z%}DdL0;*;S1b<}F3^qS}_%PGetRqi1>nD)jqsNcgkh;QF!hu95;v~EP>Djj$nNO~z z>+v8whMe-%VpmaFpS^6yk5{~H(ToId=7C_G?%tVcOpm+#jFEQ>MA-COgp|CChDO3` z$38@)4#7$#EC~3>$X5{#J+$+Fz$pQL>UY3qL?Q|+Vx0LpA>k1YIxycE>p>cVv_JIO54OIV;w|75E@Nc}|e98dy zG9pl%-RZbpTU#4JHR8xYq=EGFt!GX~Muy1y0bi5&9{_J%AjIkI+j+MS;%+wlDI*M2 zg>WGN3JwT}43O{$dJQuQfPy5)`UK8o7@@rYlr$%~LH6ln-D zfL!to2m+pml*&n@@Ybg;;`T%A9xkvMtETQj803PD4L`t8Pq@T$%)E}3bdpg zM9$^yY;Cthy?OJcXKoIqk&BDVcJ#+5G{f_kF6j)_$HJrotROU)jpRFm9Gjwit`HVY zo=t6QYp&WVy2Sk3;x}(Lg)68V=lS{hmA2Q`1IXAv6BH78>mKb!#N-t#*3_s1z zrBI6q0l_KLYw)fa+5RODXZsyOfC#Z+sOTU*W7EgVO5$G5!S5x62G-+DBM7{oRi;gU z4!_n+Y1Of?sM(eTJ>zd04|Qmgq0T51{-__sf5;MY;+>tH$hU425Xg3H$xctlx;@7! z3YPC89EoE$If>+*qoWW`{vkd-TDa{E1%LinfFuf9bi22X*=*cG`8P&>=I$FcW~R%< zkY8cyA#wJZkCT(r8~byMsnjK;EP8m-p&`O=S2Qs>pn^FX4&aellCXr0Kw!|21; zL{2*WR>>AH8yN)PA&A{Xi3dH|jcil`YtoU!hp$=NUAk0zG@$dx(FX>nK#Gt_&9vra z`D#@oS{^O^bhw}t!=2B2_4ksSf8ECoHR7+x>`i0~iG-4bgv2F*{`W`h0I8Y2gE^0u z2-JxXX}SM&;^jX@zoNpAkNsN~;Gg3%8Ki%}ZsZiBccLl2%XAU!;$`pBV?VbYX%7Hz zUq~XL3kLh~hbVTe3OA@@=`b*qqIL-e3SRfQ;v3C>A>i{*;d~r}L;oin_z_9YVMwuGOb~67AfX(teB;+EI7=T|3%neH$xh|+bFQ9^EXA6+v%j*MU zQJdOt?30p2?2)hypK=uumVYaX2*AD$sCk?N@EMUk!%OQjjnyGZ!T3gJe);0XSyW%Z zaCAdt@+l!*BQir$# z`~HfEI0yY5x{+y)ez+V7Pa8NDL`J`src3_s;WdZ5u8YV4$(yRo4UFW!My0` zPLVq^93i(xh#Au6u$M6=kUBsGU*eA;UK!_eDDwG5cH&MR4tq#*1R2a1$z!q-sp1c4 zKL6i7V>M`jW8UuGF@XkLc3QTLQv(PLyW5(LzHHm2@5ELu!ySRhLaj#02Q zoD3npH$q1%_wHewD`Ni^77|u+ZX^k#O5O0$dSU~$ko_T2r%)4##6RS+c*LIgOxs@V z;ZRdOQ-iD<+_GpqxB^+aY&rSHoNxf!~0-{O%@t6(Dtb|t;?71g9ae(XD4b7&U(5nA|&LAObpMWUqhBj>wOG)z~G1B zn^iG~{f{o|4#)-gcPg=3mY5p=JGyc#Qq<`*UhF!!1W)l9UIUq&o<4ASe7%g>oEt%F zFEe$Kz3CJN#>U1FAshz6?XG5q<`B96}w0gwfpGOp=Qb z2}b-c@_K>&3*@TrV^_Qfg~|6JqKKd$p2)|20C6kx*;ffR(3tsSc{Y7244#g!>*~@A zbocs-dw9 zK;FwsmVa$lRS`@T1@9MziHdvYAeDw9j{~1fL&qg&H&jz3Uy@%%0uR0jqeksT*!)L< z!?aY(VHQ>_x;tSN!^~q6Fnfl3je!sZuu%V$b-N%Z5orZ1(Ryu$p^D!Kk(|I`CGwW= zZ~#3oq8fru!hq(2z)FmA0PB*7J-E172M-SbpX?)$qzptiM8uWa_lejOnCfp%8v-pN zvyLtAp{GY8YljH0l!OGyk6rP|ks~rx=~(TT7=HttmX4`|gSuG)sd>EE=$fS^4=4z) zkSx$-V~S=V!brPz?j+_D7P~#DQSLtz@Sl6HF=@Lxrf`2N*h6X~E z6Pw2dD!a-32VQ9R(9nfQF&AiKPwE`rXJzTZXFx`>FLhwt6^i>uLgx4KBFDYgA8t&X zFAPcafhmhnwJ`AMJ`QaDk>(9yyI5d?@4 z0#IwsGG&GhQjX({v^~~H@A5LDO5(9MC35gBn2Rk=+t-(5QIU!vrz?%ayRQF)V)XT{mc{DISx6DAiK#Um@=75i> zT9%VjvAI7SI4q)f1u;JbekVVye;AZ()(%^w`}fQ5W4hqS#>=1ox7#K3Mog))=NGc;q{SGGYJe-~BvH0Jwz4r;zL6^iq62wdq zHtCi7qi4s!IJfRT^3JS7h=>*=rc#CIj(30uOJfS}Ac$D9I=w%c3)CuTE|r)nB8)xF zER$d0l()c)jrI|y*UG{q659k1L&JyFd?a%nfr~`NW=I-=!CAox@7=R9GTuZ-_xQ9Q z52QIBNO63~I`8%laO^l}J&TWE&>~JXE05=II8f*C)dIBmC`NH}}M`YU3FlH|% zqDW%jKEPbILP`k+YPu=` znRz{Rq?}zbVp9};-IS!FOdD|G+GoND!X1y&+7%+1)}mu*_zeks?+Ol9VIiRn0)a4&c10S90CRdk}pTw7s^#!74<+yjpyHQ89)+(+hD% z@8slU<>2JxksIvWo0N0EOyU*0ckPn&J0eebW{?}8LxnVE$;2q9WhBK+T}+rtB9B6= zq!!#Yc@$R*bcqL2`4U;ym?=agI^EV?Py@dsW^*M)2;3Ww4!Dh@OOz6NVh;0$s1v|kn5kAP`rHkrE)7$ zKS6?)(ce~`uV1`)5hAQi`Y3{>B)j5^IlFOFiBZIv`MlLG&qQcPjf@#McN(4VZb=cs zA%ZIquHi#rZ7U&mvnGVMBd~JiTJ_hes#qk!sBdJWK7sq+#8$8#Yx76>13p1^ryN>a zU)F>*zqPpkC+Csfdi_i}2{-uZYC)N!&{-)l294as)arZ}5%oX=T0kcutbgz3gUM3K zO&_q62~8huR8H(9BrsG#Vi*@gUh>c~fy^OosD?X0ALzxkqb1;J3K@uK0Xcc@*SEX@xXwuUvozM zKaK%06RLztoSgE6+_l`hv2|hyTTn7^yTkeWeQ(J~M~9HXiR2@46!0q0bukt^w6V!9 zAMk1t;%O3B0Sd=sxQ@&nAr2U4Li8e#% zh9pde5w4wc0=+7SVWtKYu!J>Hhylv|-=_T(#a=^Lr0xhvh+x`IKo|%TaYYHc_Uw^{ zmjoHfq^l?#ctKQkb!}~}V76HkEw(q+I6C_&HrPLBBB`mVkzSF!dNrs{h~?*XFEOXN z6VPmou3-%Y0WYL#B7XgLn*mmxMhuXcvZLeFIA>z=Hm}IQNSxKH82K9{WVoTM0*I7U zhYMqg4x_5*pz463b-ZyTG)+Y5zXGR8q3#C@+npprhD!QP0%kvN!Y`1q3s-GH`12wj ziNV6cf zFpbUw@Df%xqKmsB6kln_BjPwvy>7t@Y8uZ+#tnG(BeK<~6>ysqwq!tiCep5OvZL?< zLNx+73f>z+BoS|N(?CN*SVX8A)(qLZJKuJ}j(_y&W;YScfQBifeja4<77lb1i=Vw9 zQ|XtHMm&3gkaqLLB}M9>c@g99SdHYd)JCCi&q9x|EP1Q2k&!*zZe*Mg4BoTLQJQ4^PK_A1m3=DT=;r71_3bL=sVwVg0h^EbwGeLOr zAnMG_%-F3nA7@DzAR#nxq!<%4vr{#SP;S6+!1V~O0NoK;t3{)xRbXBs=8Y-{<(NR} z@GoqZfkqjSH}GcSCr17-Edo!{dpJS6Sd7(W2KkGfK+&KNL^9HCxxEYOdHBSpEQi043#uoZOd|7JBHz$SER61ow9ra2i50L@rN2KwUHyO%e%$5I#dmG){x& zw~T4UYeEP*lAxkeAYTanhYtN3> z#TMLAj0xBca}dv-(1pZ6!hCNnL{9XPYwvGw#$7;k@&yzOjK6+j8d(M?l2=gJf!gUZ zn76jjOHCrizY)>HV;BD==?PMufbE9?r309r#-lD^EnJ29!c{o)GOq@#2a1L^p;mwv zLYClx>0GotE^HHtY5qT$Agc$OMcG4V0?bPX@j;a2N4^~wnhIw5AEN7YWr~A1K@R_5 zJ#?ASu;ED(p$L=nkh|fr86{#>9Ob;$;Y)h?1}}qP>2(vS?-M5}qb=9HbD* zLYT(s^@UD$F}mDow)90* zI)A__4ge@%l7Siyh|?Egi@$W+im<#t-PEcy0vJQkf>$FBhRg5znGP80EN{npy?Qyn$*9oU2sGR7B_!13wQo z99>6X>De5Q?n<V%NyG$H86FJiAhWsG<`rCg>W13$b_a3 zhz(W@3SyiAz=gQycm@G7V(6DiX4&uFbz|=w5fxpH7;}T;Ok}=*D(Z^e+h2>__Xjfp#N-$biJVXo@;lHqb~7*-sCI%x zx-a`|H`BU?5k9qRk~rZ~%CvZ-4+-jp4(86FcGLqTp$Q>hzF%CtYcQwcaJ*(FOqpilRZHpEgsgb+Md0v*3A;qAM3H13F|L35h0KMDIm(6Z;tK0Kaw;UTwO zrX%YNp$vkK5J3UpNq8&w;AJq5=^zh3b2Y7HBk@QlK;dI}&{2E?o>kNoi7e`e^z?~V zTRf|ZcvciKJ=_CEt}@b*V|ftZyADh4s{3dTVkIgkM_9DCSw$&GdZ zda;@%i)s}v0XHE`J!3J>Y|C%9T%6J+`Bj&uxbW$&NQ!JVnk{R^ro&4XG2`PfoEV>= zp2h;5RG@8OP9kYVaRkq#fm?>`D2V8l#P<67sR+~joScMWTt+gN5aM}TrIk@QC1UDG z76`V^KK?{BisAPpILY}F-#@&>kP-;fKK3o3$9z$1a7E=2>Uz0_0ZK)HHiwBZH5zhoMZaEn^-k)3E_tYcqGDrG4XLaWLy(nO&_ zLW_M(NRdP&B4ul#kUd3`N~naCh*DIf<@dbIe1E@lzUO?;Ilsr_JAa%rkD=xBe&6?X zU)O89JMkT0B}L9|XJ_Y|H?c#!%H(x69$}T}LPW_yGnJ#38!AFUWY)&=ZCatRQL&a<;?sjlwLf8d9gDwm7ti(cF4kiH&tT;V& zbpx4wS|HJ9C?-9CQY$?kYy2ylUc9wvvR|XPnSOD}_1C43_fj`S<0`|H#-bT&i|6Bt7NUQ!4MIMhlPbduC1)pi1@=#iJ;Q-|jXXyAZ zBM{c~E@L(cqq^){R*jr^qSQyhPd>;vb~{C&dzUUsv>Wd-&rBvdOt1D!S6~TAMFN=} zh{%H0#{df8=P%W|<2fLRhuBk^mmo1lECKOQ0W#jv^^VK^qV#}{D`j=e#!yGqeD^c& zs`W_bfQ-;B`w0m5(fRokM7w}hY*Az~Co?mDDd3<^*@}fp63J8)9s|3q@91K%#m2(S zzx3G2HOaU3YM<>5RHGC%d_4_(PuOEhn?yR`NOuV9<9%>ziYsvelcU-`WC+7BgcVRk zgud-WMCdUid;pAR?ZIwCoL2p^kGzY~*#Z9vC-8SIaH5jq{P_knJH{0Ta04bbHmg#+ z*S9%7=xehP+S)$*_MLG5w1w~NMLV9lZ`78Cw$A$O!1ivJP9XU^(0!rg2mTY{;qQLP z_uuNILwtt#A8=l__+FmSY=2(cF_#Vu#-77VXNej*!37o{IxGX5LqRAei{?3B0434L zRE^2(xLwZF8!=?PYztT2 z>T@Mkg8V$1u6;!q#kxlgnLUkWCQ~uAV>jMCY`OQ zH($QIPQAeqz^JE&R_Szj_$BB3Cb(z8aN9L(xcPwESrx*ihSj=?8rlvZL!8~XA5uwI zV<`Fk(K(xN%bJ`UH`W2z5Qesm_9az=gGm0J8Im6_Mnwj>w5x8bF|S=mA#rip+dcOW zZB&`u+DEyHd4-+`ZFU2FZ1Srr`35wUq2HcYT}q`(0Ut`m9|s^UTbNPf)cMnMdV`2k zW{H$C6e*#(xi~63WA97h7r`QaL|{K@GVr+OuYJ~f^pS>85_0eERB-#|Iz|L(*RqO zMAQ^_K}+|V@~KFNn`SpF=TcG%MM|Q=u z?xU?ne@H_k!eu3UIvlJf3h?SZw0s;B%{srz&Kp)9wck4}vj@dO$CNO; z2Ay?vb6(qGzgM`1#lR=_lU$qsnNR%3ZT(LO$i#%W#wJa9KcW|e@r{oA9Y7%Daz2A{Na6NipCF^M2hVSogoQI9?B%j7lI z%F4>OjADT!!|MDzBVR|xpKG%R>X^p?9&vmW9r_mOnB@mzu4At4ErEfrb{9cm(P9uu zk{nu%kH9cE^`k(hT0Kzy;4s#S=s&WB5VYRYg?on?^R@m;FvdhqD#qWjCat5YX}}KZ zuC}aKr2(H?-Pn!kkew=tYV^`D7{@POeDXR^G6<w0{!^#nK~9oEIAz}qDHVciQQc&bGR?B?40Gxz9Y6ts;^1aw z!j84o<5b^>_KBY(A#qRxJ_)mb;uEYKO^KzdPRT!ka?Cy+@ikPC0a|N`LArhW96Xm~ zsQNs!CVPw;J0CR=VRD|R?V;9Y0{(c}U8yuZF-eVPXh*#fzy8`7Ktk-{%mb-|6L=~+ z_$~Opui4BZEaID#qGVV~5Eb?J76P>|xTP|xl*l770@H(FIP+*TwUWQT8E!kiwyMuz zk6JCpuO1lWjt$zc%(_0Lf`I@9z{#W(?70ggb7{#K1@nPfPjJ*A4&F?G5Hs{AbmrMH zfp|R9&dky~KKbxYw&b7Eb_r7)5MMpl*<rl>1`CYb%vv}K4PQaxp8dM2!-DA}>%*R%) z_`bJmD|mj?X3_@N1}NpAoru!IUi^l62jpZ6<93)*pr7BSNhfY*X2y(HcUr91t5;#f z2lbI_+Jnc$#KhPK3cAHpI_3JX_eR-BoBY2Bm~VWv(L5cwV0ZyvvZZ-I#nS^8=$d39>%=SD0`N&1920w@yw>sq2n=IBkCtE>lbBAxUrD881;)0m0c&X4zWrTLvQ;Uu zV5rwQ-^c=timjba-tZ1U#gj=jDRk)9pK*EfM%(?M{ zoN+6PvlH<%dqw;ri3+o4cP4Cb;HBpY5;mwuE}`ot*b@m~W>pkEz0ec91yyY5!o*6j z_uDvsq;;pW5ju>X>QAVPT??vJ-0@3;^=s+=ozXn>E_y=~Cdz-IkyTWJ{H9r3ml6&m zp-EIv`?TXfN;8kUwI9Umkgqya!cXuCg1@X=zaCTPP==eMY-*-0Ky|yn+JDtelm-qf5zTb}n!h>X4d)c_;p-Nk z?^eslpVJnQNbEBbeqmEl99J@!Q|W+)V^U?VM+$4}J1~Uv8yI97+qOM+;snuP zDPVw`z(N?o8wv``88Xa$lAN-3B`j2NRwFp?+piyh(F=|^$)e+&H=8~k>4%P4{%~Sd zBx;He#P}ynHlS%4DP@0<8$`wYiUedQ-(MhNuoF1jHl$&roM1B*Q17G(ls28U;$Bzd zLT|2q@8bNeV;aq=0J|o-s~h7wWnMy|AVW%4A2bXmW1%U>okDe}J)olF}SY ziC{hw?!ja!eq4Y5#)5JH=e#7%M8St?iEHgZd%HHG_PUS>ej>?B^80g;S>u_YZ||WN z2I`gDkL3^=s(1mGLUX-5fFJw#u^*2}T7IBPGQNpBM~0M0I}Ta_;P;S0f1LKUI1ZfA zIvTu*`Bcbvpn`*!uUN=PbhMY@x7;fKr|jPy?FX%cwDMsxD}(XTHJ`<&mAH^9E0fmf zI5yFZGiXaqVvBn5*RU6z1D52S2+r5*^Fql{eRU3W<`qY6H)PdiWzNFQ!=`u!tUcMQ z34^hs)5taZ(ZVPT@d$RIkE?_(#HWB`tm{{rFXC)Ie=gDrs9eQL6vqMJQyra)aer=YzenQ z_lmxAJ$)e4cfO=G;fF~Ta-xQJWK5^9BZ+HWv}i;n@{;TzPEI_5+*Q(4WPL1YaRF9# z`Xt$brKKdFzWngPc>45%i8VjqyipQ%3ks(t(*P|1P**Zcm{^Oc5y60Vtia-H;V zNv-}!&KM1Fs>_n0>wYDkl&Cs)=<5)^5Bd>KGt4r(QY#oUQ5{g8V~bpia^hlAD`)|U zAxu1cFd82+0|E{mop0|iSVYGY9Uxhqixyc$+V3`6KC%h;I&(qz_^&M3w>fc@V=_Ge z1o#^MfZ;aVrB3tt%JncsBbUX!db!^~p8=jM*t>$}aRf_NKdi2#njEB=+L^#4wUtR% z0&AwkIL+{RM`!WRJAJSPEDap+>2>d!s^8E7qXYnC%ZPS)|6~-0`Pt~`29hRMji&82 zK#jy|NcIsBWX|%-@Yc38mx9bmeieiS?Ot%i?dN9>`@UHO!Y=m~FylyK8WOs~v=hw% z47(!2Z_(9I;w3>X=Pf(L+JjVSNf#K*LYGbj4-k~aaNa-e3mnDGFLpQpC22@$0C?QT z$)nP`^)1w(>7N{uF6ExHZAjNY7!affT%9~EkLo;iVE;#t_F#KJk9?~1%!yUlAA}^N z>#9;C0Hq=e@Z%vgfojpsz&~rcbx1YO!29(Y_@rG3RnU*A$M!G%!b4Y{9`7Cq9+P%) zsV(oCtdk?~F8tH`8-ll8l(;giP@6?XGd+Q2Esz$*s{~S-aV^0{5;mWQIP)*46y1)} zZ>&MQVYHiK&{h!5qzTOf@woX}F(pq-g+Ux{0vF)-kK4JNR#FrkP_1yZ`*mCg!@oJ~ z&*5ovI0K$C(~*YqAmSZl@m{i#~pwr)Mbj4j%~En6B*I;4|GqJrn76TuKP zI3!QLxyF-XpIM%^TFX=k^Rh%V#L{IW~4SU@y@FtZAXU(WHHWO?j(ustej7_zpx zc%EEzNgJdUJLFO8%Ht*`OAE613TcDO#l^5q~p$eRGlEWN05itxa)pajH5H1^`hTgMvB_ z3zDl1n1j$0yDYkJJ}2v&TNqAY33E5sfIXmtw>Q=60~&HNUVHd(h339_P6PV%?K|{T zQAHl*+w1Dr8`rOo(!B$ZEjm$JbFm5r1O$u-2HMm-RXNimp3|q5ii#)wckE=={9?Uf z%^m5ds3#Im^YZ3qqe+t@TFz_kKvObt|G>5EwWX-BpSyo^L@Z(-+39nTQ{bq|lH6HW zVndr1GKxOLHjU!!n#4@tYLZk!^nWHr(u%_>C*ZpV>4N4#=%{(JhR9GOxAQZvuDNtS zGI^|5{m77z?udX~vMn!dm~v_C6r&Sq7Efc!_WbPRK0tzTCIk1Rt~&kea-c=n-y@qW zyZ<#g*3afUd?vT zzOqvy6&VhKj~&~K|wFpR(($Db4HY_&{NYmiy!RA81;g!Vy zl#H+r-I>&VCtu-@>shoKAlcac(6FZ;izaArRfvU}@6^%0Q+0)kTzzf#mT@QfwCJr# zi8=`4rs_M@+*~5*qy`>Z_3orY1~`@xH?s&IKq=v2y^px?Im>$5w7jCCg^^B8kVG{L z>aQg+(uk}nFQb4MfWdEIXQnSlai_)GnUU*h+Z#I_5{Vs2g3r_P8yCOH<78Sl^Ni+! z`Dd&zG`RT9;zpo=U4)MW$7g=1)0jAa!GaSHf&v2rGs+Nh(6&G{G!)CYot->e)Us9j zAF>}LCx<6F8={tDFmNx7)z#4vca6lj(fw2Y2(j=c_zy(4M~vHvup{42HY=ERcwnE* zYX%?iM2J>Mf+?AigsdlS?hq_C0ZF$wNs{Q07e)STtp?*OD|vOLlY}IeE#<}}PC$Q9 zsz1mM0Utul_zNi2yZblM^Yhs`628;7wsFhejt16-vw&;UnG)Z}7zqy$z*cfy#h}BV z(IlH@1{%M8llKT{pGAbvp)2CCJ7oEJN^|@)Ee`t-U87 z!s6SQVac^HdTe>Rm9#JyQ2&%0_;Oz1&45Ci1GGlJP;%s5Wo6}?@R;XwX(n7|w7N2b z1;+4ai}nwZ-N1QwRWK9pcwG9TV8mx2LF|+!_atGO!&!Y*MKjI1-~m{Lg}I@qV$!)upn@^uaZP{cDDHOj{^YF9HqQ|h-Olk1DalkUn*m%lLX{+pWr7m z6n!LPd~XgN&DhZ+NDPg0DT%1qf9qyyuO2f`*!_vLq}8-|wY4p>K_n(Tjp>dqA&-sh zvdvw6U5nJLD$QIsAF$4`>v_uuU}Fb#R3PG}%oS5_9p11;=b(!BmZ+%muB%6xHrn-l zH2B}3DgGNr@UMm&w0g4`wTG%E>w2KSHf?2GmjbKP!qT#=jnC+6|Ma_cg{+Ms&aZzf zFC{!eq{q@YS<|~9672biUTf=)9YaSffGq5)^dT>AJ*kmZR^O*pLzbNJ(8^m>^R9yj zpO21%fEf}M-Jk~YoTZY|J0Gx=+YK5izzD<|fLL$I^5w*p`C-vm!dqKjM+c1hViJ1_ zZFhHGKho3H(YhQJ9NHhRxp}ZN3HpF#Wwjn{7|{@I$P&mhjvWII$qfAT`(U0K^?qa| zXr?w|FTn8Buwr`NJ@|9*a&NvqTe@^4R$*BKuwRJGFg>)zh`^ud*V^`G!#7N?VB^!H!0fj@EHvfQA>D zRv+OvPJRRE*^E?sFWv0!UAv&}5@_={8925CEEazmT`JI7RYVO^*yCrkTO$p3MW$f2j=rBaDaPxDWwrLLVWK9N$kavHdobH6iP<94GolK%wau` zndtjXZK51PhAw6I4|Yc z*|SqX<;{7`6KhZE9Di*05YUrzOTrKR!nr46Eq9S2z4X&9Pd776`1<9G&LjJV7rIieJmj z+((ndMT2Nv6kyrLc@|L83oGkT%)SumSyKHJ2;FoF&<-LyZO}NR}Ws6G@m7 zJTeuDYr$$EBJrfSr9_jpZ^Xw_5>*}(d4Np`*bdE06QD%VPNVdsM>PIorzVc>`XfSwAN1v5)aLj<4_ zmCW|DWiX%wa6!hbkgL-4<)}W0F)hCE10a>H+|2kqYA3{#^8RK0ojwG!CSDm$3DbPg zfWDkiej>k)wC6YD zg$Vqkz2u%z%JYHglCwD3Zfir+0r?|Ey|`Jo1DZjfEpU;uGHXvYU7!){pw-x z7`fL2_)g2cT6lJG*rG;-T3v@^p5Kgq4})Ve1>hD^e_`K%@ADAk_wbH6o*p*Un||sO zjh%#XF!J7HS4#e;KQBi&SIafNRC!HVVo#CFEd6oZ7KgBM&xmO;{dw-vO(1!;cv_2e z8+NWc3W-~}wH2Czbul6sXM#}fm%X@dBcCu27z%_TzgYuvJC?i z(VgffB)LhJK*z#D|2KT2#kcU0Y{j`~<^C*BjH}JF zztm+u4{T^Kqi$&@kK*&!`uE=ASyT@d?fFLC))nkN*}nI=Ll5V8`94k$%^&Jjb406r zvaMNiwQ8U9I(LH2&ze8(lWLxRUwg>MZJvYmTU)kxoS&Vm{=j{6dFQ=1jdQ)@SHvGK zao5XT?^^n_vhoQ)g{IM8;$IR12O zxbuZ-_DZ9lezM~#gYT3SN}Mu$lOimXu__|sj#CUQ{TP~A2=Nz;d&fdT<_z{<`8jo* zZ@w?#x3Vm7JBR`ge=ywk{)s(8+(fMC>wCm9Y%3-gnl|(?M6kND4V7eT0@Q2rqZ-VH z(vY%3vmbfKj*F!O96qT=K3!C>wdWxT(*aK2%=uw^&Pq~76>?3B+3=fQSxJr>9Th@T z(BQqMS%yz<>?yYc)2_)SLIRmn^M-?T@*5#OQC>n`A8JE6jE4>#ioyr%ZRIq%%s6tJ zMss_%CT09Km4-W7XVZ?O&er(a!FPOpeUMNE_nq-KB%}|X4&Q;MgyAYMU`q}+F{rE< z7|~l!F{nz%;p_$}e8WoqOH7FCC~L)f?!xtrgs?F)HNE@bfw-zAqL(>Vupm1(OME3~ zG8~5e_~VZROCGfh3w%Z^K?d0|sy$Y2nxfIj%0Lj)Gc$dN=D$66cPdvI>xDd33JeIC zK$(}ysECS+O3G;G5TzQI6LCN5%Xgt6gaC}M#3}PId!m8yJ8$@h>+02M4y5&%Mm18a_SApLYP^#fAl(*j=%`JX1W;pE~ z)T#VsRn;nCih=jb%gZIu1P_HoL(sa8wg|s!GDG6jTSg?Of^1N~5-AuGg=%+UDYxHs zUvu-ujVD}S`RCMydP>kJ%P?O=lEdQENlY|m>U62`w`=&BHeXN~Vj{t`=_}=S9t9n$ z9l#sQ^JRX%D7Ju^1(xK{mYa zSL)0kVjNOP+LK;g^-Tsn1sNO4yccjdWA~S%8kHVCdR{ZaxDmgU1w&Y6we_V8h{oyP zV@odf`ZcLZm$BMO_wQe}4ajr)yP^5TtIV}8zk!Ok&+k&pBwg=Px7-vKh;sw z`nGL5VCIet2ejpD>5I8Eg860A!tle;xsf(Q*F8u|8V!jATBU8Q8IU}98$q0H9a0;` zUcM~X7Y#Sw?&WoR?zu?&5Pmm{>=d1aOMi_06`fcJXjx)zcFWO?ruzB&Z@oQt4v<=V zFGEJ-tnd=criGN>X@+TSw{xfA(Z}zO8UZcJ^kV!#R8X83>HUkkZdf^xFM-(_7?8X_ z*{)fGF>xE0ht>a#>VbOVvanxqgcs~RFE8H>a2JOLY(Sqhz_wL-md1@r)e9OGf;GuF zo|q`n%QJ4o8c*o-!RU%B>um2PjZ=`D=FVsb$s;c^gXhiJ!x8|OEfqMaA;!4uneCN}`UU2)i0zSmv-hN7j zG41SujG5Nfi8KlF6VKX&OD+*WqeSF?HsL5?D#5XE8@7&y=>UxvU><<(D_ym&T@Jiz zZ@|LqzQ)VYHehr4m^Kdq?qy!0&7@OOklT-N)Q=Y@>Nd&f=IznHi|kua#`|_dMCG(1 zE|7L~?uDlq0*QSJpd6gX!Nx%#cda{RmC!wo1;hqePWntm<(fO07lGy}fJ`{;VayqY zRS`C>KR?}fe8y?Vbo-$qBLq&7;AVI^C;tQz&pp+&R{$(;$A4v{x(VK%xPn+5 z=0S$)@0XP#X=ezOTTw(KkZOO7;*8BhE{zB}3D{xdAxRCP?Vb-I(mCXi8psuOP+qqv%Sfs9sQtP*bLMK} z4qpBfdr1B`V>V-DQoow2sw#q5k|4Q#J+Jb(I8QH^CH0ZXuoamo;DdYJvGRPsZw-l1 zw{FLtX1#@mglwu^eigw|NPl%S1p@uE;(a}40<78csTEHaX`uEgG%u?B^hsKK35vXU zakw10WISTfo9d?x1RC&DaOz#4N@V+lf1CXJ zyD{`1{NwyMK7vPP!f#uS4^QfZkSO_Tive{0RCgcR=G7ywf0-T=DJxaO)YFc+07Og>Nh;8SqZh)vA~k3Wht;lJ4#CeucJWSQ|K>7ly9T`Xd4tbNMpr zs|l_iXZV~2_9?R(uL-TE+PQ!Kosz$SrI}GqiV`sD9|ztPocGMTl5BU=?t;mzSt*DM z4i@}wZy&_IaCxtZqbDZKsEZ;Xu=J$_#b|+xpA3b-P zjhD4S$3%DuIxEyK>wQvKtg`jXQ{S2}g=QY=boj7WP99$b^va-8kXmYZ#l z_3OSfPKE4!gqoBnL6FI`7(Hf8V8JCV6}6J(Bh=_4P`)#mEWdX?Jif_bR!O|Ie|@e2{AkByqF(yAr{|$u4UnK0;IuGK^#t+F+*)d zT+Z8t(YNQCL_}Ydfn1!66eLkOlttxGjhHe=jar*lEsbrGMQfYz3O|(r{rg+Ki*Zck zq6j|o{P`hi<*zL)Ecl%CW+WqwdW@@4?)F<=VM}zRzTz8?1o|?>;C1k#@We$Hi*=?F=yJP zPWR`a$w9rp2_;Soh!s#Msu!-O2`3F2)~_!pH|G&Th;Dcy!!l0&Fm2i+hbV3e+6BD9 zX)Adv=dAkDB@kJ@l2%l#Kd?!2u`9`SWD@WfWO|avm=GTg)eT1{xE|xQWa&Vy(FKV3 z9cP&Qb&M&f6@h(t9*85}o5$KG4r=+z&g)*s4=s|sboVNSr@a+@4o7}cuhZvvQK*O? z5bzlq9xj&=$kctYw2dnqnNWbBhU}&>0EQBDzzOm#^D0+~5zE(ueB$3%aoGxOyxh41 zPla35XV0F!uAr8ZRf8_+*1db%`4QsLXVz(2`P(O20z0-Ydx8|8o~c5>tkl* zR-^8aot#=hmSI3v0?Gq0p@BKDsG->B;gmaRuMo)PkZVB)DRpAG5pYhzk|Y#@fy|@s zn>wI|Pa^pZo63xjhOi9objttn!qa9C3yx&(PkO%2Y!BDcw4qor0g6)|F2F0tNrH{m zFf9TTngM~{%loY)h6V^)1(+$R->9$TVR6&L6nd77cQwyGtdKNAge-D>cG!TrIdh_H z;0dSHyTqA?=2q?@1BQ6)g{t{mXsJSW8mn7*}@h+4Jaq z+$WoNqWB{CN%C=!E?HlCH7Z+|$_nNpZ;Bq09Z4fd_pxh2;n;wSvtBmq*LUePuZQ>U z-o=xHqVnX#3s!w;cCyPFnaa%uX|Fstb##dZx+V~=sSrsB4lNIPbq2yHjv6mkB6~OI sX}&6>FZTM^)4<=&6=Gt%7+R-1d8W^>Nk(6k75rmlFllVW=-KQ356yke@Bjb+ literal 0 HcmV?d00001 diff --git a/__tests__/html/__jest__/WebChatEnvironment.js b/__tests__/html/__jest__/WebChatEnvironment.js index 125546917b..4f753831ae 100644 --- a/__tests__/html/__jest__/WebChatEnvironment.js +++ b/__tests__/html/__jest__/WebChatEnvironment.js @@ -4,7 +4,7 @@ const NodeEnvironment = require('jest-environment-node'); const { browserName } = require('../../constants.json'); const hostServe = require('./hostServe'); -const serveJSON = require('../serve.json'); +const serveJSON = require('../../../serve-test.json'); class WebChatEnvironment extends NodeEnvironment { constructor(config, context) { diff --git a/__tests__/html/adaptiveCards.tapAction.html b/__tests__/html/adaptiveCards.tapAction.html new file mode 100644 index 0000000000..1ebe2ad67f --- /dev/null +++ b/__tests__/html/adaptiveCards.tapAction.html @@ -0,0 +1,113 @@ + + + + + + + + +
+ + + diff --git a/__tests__/html/adaptiveCards.tapAction.js b/__tests__/html/adaptiveCards.tapAction.js new file mode 100644 index 0000000000..5b07edc033 --- /dev/null +++ b/__tests__/html/adaptiveCards.tapAction.js @@ -0,0 +1,8 @@ +/** + * @jest-environment ./__tests__/html/__jest__/WebChatEnvironment.js + */ + +describe('Adaptive Cards', () => { + test('with "tapAction" prop should react to click, ENTER, and SPACEBAR', () => + runHTMLTest('adaptiveCards.tapAction.html')); +}); diff --git a/__tests__/setup/NUnitTestReporter.js b/__tests__/setup/NUnitTestReporter.js index b86d71f51f..2f34d0779d 100644 --- a/__tests__/setup/NUnitTestReporter.js +++ b/__tests__/setup/NUnitTestReporter.js @@ -185,9 +185,11 @@ class NUnitTestReporter { { minStartTime: Infinity, maxEndTime: -Infinity } ); - xml['test-run']['@start-time'] = new Date(minStartTime).toISOString(); - xml['test-run']['@end-time'] = new Date(maxEndTime).toISOString(); - xml['test-run']['@duration'] = Math.max(0, maxEndTime - minStartTime) / 1000; + if (isFinite(minStartTime) && isFinite(maxEndTime)) { + xml['test-run']['@start-time'] = new Date(minStartTime).toISOString(); + xml['test-run']['@end-time'] = new Date(maxEndTime).toISOString(); + xml['test-run']['@duration'] = Math.max(0, maxEndTime - minStartTime) / 1000; + } xml['test-run']['test-suite'] = xml['test-run']['test-suite'].map(testSuite => { const { 'test-case': testCases } = testSuite; diff --git a/package.json b/package.json index ae1f627c14..f8d31b46ef 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "eslint": "lerna run --parallel --stream eslint", "posteslint": "npm run prettier-readmes", "prettier-readmes": "prettier --write **/**/*.md --tab-width 3 --single-quote true", - "start": "concurrently --kill-others --raw \"serve\" \"serve -p 5001 -c __tests__/html/serve.json __tests__/html\" \"lerna run --ignore playground --parallel --stream start\"", + "start": "concurrently --kill-others --raw \"serve\" \"serve -p 5001 -c serve-test.json\" \"lerna run --ignore playground --parallel --stream start\"", "tableflip": "npx lerna clean --yes --concurrency 8 && npx rimraf node_modules && npm ci && npm run bootstrap -- --concurrency 8", "test": "jest --watch", "test:ci": "npm run test -- --ci --coverage true --no-watch", diff --git a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js index 716a38b122..d6246d1828 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js +++ b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardRenderer.js @@ -222,7 +222,7 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled const [actionsPerformed, setActionsPerformed] = useState([]); const [adaptiveCardsHostConfig] = useAdaptiveCardsHostConfig(); const [disabledFromComposer] = useDisabled(); - const [error, setError] = useState(); + const [errors, setErrors] = useState([]); const [lastRender, setLastRender] = useState(0); const activeElementIndexRef = useRef(-1); const adaptiveCardElementRef = useRef(); @@ -235,18 +235,46 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled const disabled = disabledFromComposer || disabledFromProps; - const handleClick = useCallback( - ({ target }) => { + // TODO: [P2] We should consider using `adaptiveCard.selectAction` instead. + // This callback will not listen to "click" or "keypress" event if the component is disabled or does not have "tapAction" prop. + const handleClickAndKeyPress = useCallback( + event => { + const { key, target, type } = event; + // Some items, e.g. tappable text, cannot be disabled thru DOM attributes - if (!disabled) { + const { current } = contentRef; + const adaptiveCardRoot = current.querySelector('.ac-adaptiveCard[tabindex="0"]'); + + if (!adaptiveCardRoot) { + return console.warn( + 'botframework-webchat: No Adaptive Card root container can be found, probably on an unsupported Adaptive Card version.' + ); + } + + // For "keypress" event, we only listen to ENTER and SPACEBAR key. + if (type === 'keypress') { + if (key !== 'Enter' && key !== ' ') { + return; + } + + event.preventDefault(); + } + + // We will call performCardAction if either: + // 1. We are on the target, or + // 2. The event-dispatching element is not interactive + if (target !== adaptiveCardRoot) { const tabIndex = getTabIndex(target); // If the user is clicking on something that is already clickable, do not allow them to click the card. // E.g. a hero card can be tappable, and image and buttons inside the hero card can also be tappable. - if (typeof tabIndex !== 'number' || tabIndex < 0) { - tapAction && performCardAction(tapAction); + if (typeof tabIndex === 'number' && tabIndex >= 0) { + return; } } + + performCardAction(tapAction); + scrollToEnd(); }, [disabled, performCardAction, tapAction] ); @@ -331,10 +359,9 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled const { failures } = adaptiveCard.validateProperties(); if (failures.length) { - // TODO: [P3] Since this can be called from `componentDidUpdate` and potentially error, we should fix a better way to propagate the error. - const errors = failures.reduce((items, { errors }) => [...items, ...errors], []); - - return setError(errors); + return setErrors( + failures.reduce((items, { errors }) => [...items, ...errors.map(({ message }) => new Error(message))], []) + ); } let element; @@ -342,14 +369,15 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled try { element = adaptiveCard.render(); } catch (error) { - return setError(error); + return setErrors([error]); } if (!element) { - return setError('Adaptive Card rendered as empty element'); + return setErrors([new Error('Adaptive Card rendered as empty element')]); } - error && setError(null); + // Clear errors on next render + setErrors([]); restoreInputValues(element, inputValuesRef.current); @@ -369,7 +397,7 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled adaptiveCardElementRef.current = undefined; }; - }, [adaptiveCard, adaptiveCardsHostConfig, contentRef, error, HostConfig, renderMarkdownAsHTML]); + }, [adaptiveCard, adaptiveCardsHostConfig, contentRef, HostConfig, renderMarkdownAsHTML, setErrors]); useEffect(() => { // Set onExecuteAction without causing unnecessary re-render. @@ -404,14 +432,19 @@ const AdaptiveCardRenderer = ({ actionPerformedClassName, adaptiveCard, disabled return () => undoStack.forEach(undo => undo && undo()); }, [actionsPerformed, actionPerformedClassName, lastRender]); - return error ? ( - -
{JSON.stringify(error, null, 2)}
+ const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined; + + return errors.length ? ( + + {errors.map(({ error, message }, index) => ( +
{JSON.stringify({ error, message }, null, 2)}
+ ))}
) : (
); diff --git a/packages/testharness/src/index.js b/packages/testharness/src/index.js index 7425ed43e8..58182b38ce 100644 --- a/packages/testharness/src/index.js +++ b/packages/testharness/src/index.js @@ -38,6 +38,21 @@ import shareObservable from './utils/shareObservable'; import sleep from './utils/sleep'; import subscribeConsole, { getHistory as getConsoleHistory } from './utils/subscribeConsole'; +function waitForFinishKey() { + const { promise, resolve } = createDeferred(); + const handler = event => { + (event.code === 'CapsLock' || event.code === 'ShiftRight') && resolve(); + }; + + window.addEventListener('keyup', handler); + + log('WebChatTest: After you complete the last step, press CAPSLOCK or right SHIFT key to continue.'); + + return promise.finally(() => { + window.removeEventListener('keyup', handler); + }); +} + window.Babel.registerPlugin( '@babel/plugin-proposal-async-generator-functions', BabelPluginProposalAsyncGeneratorFunctions @@ -78,18 +93,22 @@ if (!webDriverMode) { break; case 'send keys': - log(`WebChatTest: Please press this key sequence: ${job.payload.keys.join(', ')}.`); - await sleep(1000); + log( + `WebChatTest: Please press this key sequence: ${job.payload.keys + .map(key => (key === '\n' ? 'ENTER' : key === ' ' ? 'SPACEBAR' : key)) + .join(', ')}.` + ); + await waitForFinishKey(); break; case 'send shift tab': log(`WebChatTest: Please press SHIFT-TAB key.`); - await sleep(1000); + await waitForFinishKey(); break; case 'send tab': log(`WebChatTest: Please press TAB key.`); - await sleep(1000); + await waitForFinishKey(); break; default: diff --git a/packages/testharness/src/pageObjects/runHook.js b/packages/testharness/src/pageObjects/runHook.js index 2353afa786..8278449792 100644 --- a/packages/testharness/src/pageObjects/runHook.js +++ b/packages/testharness/src/pageObjects/runHook.js @@ -8,6 +8,7 @@ export default function runHook(fn) { activity: { from: { role: 'user' }, name: '__RUN_HOOK', + ref: { count: 0 }, timestamp: new Date(0).toISOString(), type: 'event', value: { fn, resolve } diff --git a/packages/testharness/src/token/fetchDirectLineToken.js b/packages/testharness/src/token/fetchDirectLineToken.js index f445104d8f..2cfcf4651a 100644 --- a/packages/testharness/src/token/fetchDirectLineToken.js +++ b/packages/testharness/src/token/fetchDirectLineToken.js @@ -1,5 +1,5 @@ -export default async function() { - const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' }); +export default async function(url = 'https://webchat-mockbot.azurewebsites.net/directline/token') { + const res = await fetch(url, { method: 'POST' }); if (!res.ok) { throw new Error('Failed to fetch Direct Line token.'); diff --git a/packages/testharness/src/utils/createRunHookActivityMiddleware.js b/packages/testharness/src/utils/createRunHookActivityMiddleware.js index 19d37b5e6c..def343445e 100644 --- a/packages/testharness/src/utils/createRunHookActivityMiddleware.js +++ b/packages/testharness/src/utils/createRunHookActivityMiddleware.js @@ -1,4 +1,4 @@ -const { createElement, useRef } = window.React; +const { createElement } = window.React; const RunHook = ({ fn, resolve }) => { resolve(fn(window.WebChat.hooks)); @@ -6,16 +6,10 @@ const RunHook = ({ fn, resolve }) => { return false; }; -const RunHookOnce = props => { - const renderCount = useRef(0); - - return !renderCount.current++ && createElement(RunHook, props); -}; - function createRunHookActivityMiddleware() { return () => next => ({ activity, ...others }) => { if (activity.type === 'event' && activity.name === '__RUN_HOOK') { - return () => createElement(RunHookOnce, activity.value); + return () => !activity.ref.count++ && createElement(RunHook, activity.value); } return next({ activity, ...others }); diff --git a/__tests__/html/serve.json b/serve-test.json similarity index 97% rename from __tests__/html/serve.json rename to serve-test.json index 5aa3bb001c..7a8a4866c0 100644 --- a/__tests__/html/serve.json +++ b/serve-test.json @@ -10,7 +10,6 @@ ] } ], - "public": "../..", "rewrites": [ { "source": "/assets/:filename", From adca75650ad011c6f354f2f2fd5abe3051396bc1 Mon Sep 17 00:00:00 2001 From: William Wong Date: Wed, 3 Jun 2020 10:05:03 -0700 Subject: [PATCH 2/2] Add entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6287b901..756ad90b52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Fixes [#1340](https://github.com/microsoft/BotFramework-WebChat/issues/1340). Card container should not be focusable if they do not have `tapAction`, by [@compulim](https://github.compulim) in PR [#3193](https://github.com/microsoft/BotFramework-WebChat/issues/3193) +- Fixed [#3196](https://github.com/microsoft/BotFramework-WebChat/issues/3196). Cards with `tapAction` should be executable by ENTER or SPACEBAR key, by [@compulim](https://github.com/compulim) in PR [#3197](https://github.com/microsoft/BotFramework-WebChat/pull/3197) ### Changed