@@ -6,77 +6,78 @@ import { expect as expectWdio, SoftAssertionService, SoftAssertService } from '.
66vi . mock ( '@wdio/globals' )
77
88describe ( 'Soft Assertions' , ( ) => {
9- // Setup a mock element for testing
10- let el : ChainablePromiseElement
119
12- beforeEach ( async ( ) => {
13- el = $ ( 'sel' )
10+ it ( 'should handle promises properly and return a promise when matchers are used with Promises or Elements' , async ( ) => {
11+ const softService = SoftAssertService . getInstance ( )
12+ softService . setCurrentTest ( 'promise-0' , 'test name' , 'test file' )
1413
15- // We need to mock getText() which is what the toHaveText matcher actually calls
16- vi . mocked ( el . getText ) . mockResolvedValue ( 'Actual Text' )
14+ expect ( expectLib ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
15+ expect ( expectWdio ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
16+ expect ( expectWdio ( Promise . resolve ( true ) ) . resolves . not . toBe ( false ) ) . toBeInstanceOf ( Promise )
17+ expect ( expectWdio . soft ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
1718
18- // Clear any soft assertion failures before each test
19- expectWdio . clearSoftFailures ( )
20- } )
19+ const elementToHaveText = expectWdio ( $ ( 'element1' ) ) . toHaveText ( 'Valid Text' )
20+ expect ( elementToHaveText ) . toBeInstanceOf ( Promise )
2121
22- describe ( 'expect.soft' , ( ) => {
22+ // TODO remove await once $$() support is merged
23+ const elementsToHaveText = expectWdio ( await $$ ( 'elements2' ) ) . toHaveText ( 'Valid Text' )
24+ expect ( elementsToHaveText ) . toBeInstanceOf ( Promise )
2325
24- it ( 'should handle promises properly and return a promise when matchers are used with Promises or Elements' , async ( ) => {
25- const softService = SoftAssertService . getInstance ( )
26- softService . setCurrentTest ( 'promise-0' , 'test name' , 'test file' )
26+ const elementsNotToHaveText = expectWdio ( await $$ ( 'elements3' ) ) . not . toHaveText ( 'Not Valid Text' )
27+ expect ( elementsNotToHaveText ) . toBeInstanceOf ( Promise )
2728
28- expect ( expectLib ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
29- expect ( expectWdio ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
30- expect ( expectWdio ( Promise . resolve ( true ) ) . resolves . not . toBe ( false ) ) . toBeInstanceOf ( Promise )
31- expect ( expectWdio . soft ( Promise . resolve ( true ) ) . resolves . toBe ( true ) ) . toBeInstanceOf ( Promise )
29+ await Promise . all ( [ elementToHaveText , elementsToHaveText , elementsNotToHaveText ] )
3230
33- const elementToHaveText = expectWdio ( $ ( 'element1 ' ) ) . toHaveText ( 'Valid Text' )
34- expect ( elementToHaveText ) . toBeInstanceOf ( Promise )
31+ const elementSoftToHaveText = expectWdio . soft ( $ ( 'element4 ' ) ) . toHaveText ( 'Valid Text' )
32+ expect ( elementSoftToHaveText ) . toBeInstanceOf ( Promise )
3533
36- // TODO remove await once $$() support is merged
37- const elementsToHaveText = expectWdio ( await $$ ( 'elements2' ) ) . toHaveText ( 'Valid Text' )
38- expect ( elementsToHaveText ) . toBeInstanceOf ( Promise )
34+ const elementsSoftToHaveText = expectWdio . soft ( await $$ ( 'elements5' ) ) . toHaveText ( 'Valid Text' )
35+ expect ( elementsSoftToHaveText ) . toBeInstanceOf ( Promise )
3936
40- const elementsNotToHaveText = expectWdio ( await $$ ( 'elements3 ' ) ) . not . toHaveText ( 'Not Valid Text' )
41- expect ( elementsNotToHaveText ) . toBeInstanceOf ( Promise )
37+ const elementsSoftNotToHaveText = expectWdio . soft ( await $$ ( 'elements6 ' ) ) . not . toHaveText ( 'Not Valid Text' )
38+ expect ( elementsSoftNotToHaveText ) . toBeInstanceOf ( Promise )
4239
43- await Promise . all ( [ elementToHaveText , elementsToHaveText , elementsNotToHaveText ] )
40+ // Ensure all assertions are awaited to avoid conflicts in other tests
41+ await Promise . all ( [ elementSoftToHaveText , elementsSoftToHaveText , elementsSoftNotToHaveText ] )
42+ } )
4443
45- const elementSoftToHaveText = expectWdio . soft ( $ ( 'element4' ) ) . toHaveText ( 'Valid Text' )
46- expect ( elementSoftToHaveText ) . toBeInstanceOf ( Promise )
44+ it ( 'should handle non-promises matchers properly by not using promises' , ( ) => {
45+ const softService = SoftAssertService . getInstance ( )
46+ softService . setCurrentTest ( 'non-promise-1' , 'test name' , 'test file' )
47+
48+ // Base line on Jest 'expect' library
49+ expect ( expectLib ( true ) . toBe ( true ) ) . toBeUndefined ( )
50+ expect ( expectLib ( true ) . toBe ) . toBeInstanceOf ( Function )
51+ expect ( expectLib ( true ) . toBe ( true ) ) . not . toBeInstanceOf ( Promise )
52+ expect ( expectLib ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
53+
54+ // wdio expect
55+ expect ( expectWdio ( true ) . toBe ( true ) ) . toBeUndefined ( )
56+ expect ( expectWdio ( true ) . toBe ) . toBeInstanceOf ( Function )
57+ expect ( expectWdio ( true ) . toBe ( true ) ) . not . toBeInstanceOf ( Promise )
58+ expect ( expectWdio ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
59+
60+ // wdio expect.soft
61+ expect ( expectWdio . soft ( true ) . toBe ( true ) ) . toBeUndefined ( )
62+ expect ( expectWdio . soft ( true ) . toBe ) . toBeInstanceOf ( Function )
63+ expect ( expectWdio . soft ( true ) . toBe ) . not . toBeInstanceOf ( Promise )
64+ expect ( expectWdio . soft ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
65+ } )
4766
48- const elementsSoftToHaveText = expectWdio . soft ( await $$ ( 'elements5' ) ) . toHaveText ( 'Valid Text' )
49- expect ( elementsSoftToHaveText ) . toBeInstanceOf ( Promise )
67+ // Setup a mock element for testing
68+ let el : ChainablePromiseElement
5069
51- const elementsSoftNotToHaveText = expectWdio . soft ( await $$ ( 'elements6' ) ) . not . toHaveText ( 'Not Valid Text' )
52- expect ( elementsSoftNotToHaveText ) . toBeInstanceOf ( Promise )
70+ beforeEach ( async ( ) => {
71+ el = $ ( 'sel' )
5372
54- // Ensure all assertions are awaited to avoid conflicts in other tests
55- await Promise . all ( [ elementSoftToHaveText , elementsSoftToHaveText , elementsSoftNotToHaveText ] )
56- } )
73+ // We need to mock getText() which is what the toHaveText matcher actually calls
74+ vi . mocked ( el . getText ) . mockResolvedValue ( 'Actual Text' )
5775
58- it ( 'should handle non-promises matchers properly by not using promises' , ( ) => {
59- const softService = SoftAssertService . getInstance ( )
60- softService . setCurrentTest ( 'non-promise-1' , 'test name' , 'test file' )
61-
62- // Base line on Jest 'expect' library
63- expect ( expectLib ( true ) . toBe ( true ) ) . toBeUndefined ( )
64- expect ( expectLib ( true ) . toBe ) . toBeInstanceOf ( Function )
65- expect ( expectLib ( true ) . toBe ( true ) ) . not . toBeInstanceOf ( Promise )
66- expect ( expectLib ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
67-
68- // wdio expect
69- expect ( expectWdio ( true ) . toBe ( true ) ) . toBeUndefined ( )
70- expect ( expectWdio ( true ) . toBe ) . toBeInstanceOf ( Function )
71- expect ( expectWdio ( true ) . toBe ( true ) ) . not . toBeInstanceOf ( Promise )
72- expect ( expectWdio ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
73-
74- // wdio expect.soft
75- expect ( expectWdio . soft ( true ) . toBe ( true ) ) . toBeUndefined ( )
76- expect ( expectWdio . soft ( true ) . toBe ) . toBeInstanceOf ( Function )
77- expect ( expectWdio . soft ( true ) . toBe ) . not . toBeInstanceOf ( Promise )
78- expect ( expectWdio . soft ( true ) . not . toBe ( false ) ) . not . toBeInstanceOf ( Promise )
79- } )
76+ // Clear any soft assertion failures before each test
77+ expectWdio . clearSoftFailures ( )
78+ } )
79+
80+ describe ( 'expect.soft with single element' , ( ) => {
8081
8182 it ( 'should not throw immediately on failure' , async ( ) => {
8283 const softService = SoftAssertService . getInstance ( )
@@ -88,7 +89,12 @@ describe('Soft Assertions', () => {
8889 const failures = expectWdio . getSoftFailures ( )
8990 expect ( failures . length ) . toBe ( 1 )
9091 expect ( failures [ 0 ] . matcherName ) . toBe ( 'toHaveText' )
91- expect ( failures [ 0 ] . error . message ) . toContain ( 'text' )
92+ expect ( failures [ 0 ] . error . message ) . toEqual ( `\
93+ Expect to have text
94+
95+ Expected: "Expected Text"
96+ Received: "Actual Text"`
97+ )
9298 } )
9399
94100 it ( 'should support chained assertions with .not' , async ( ) => {
@@ -213,6 +219,44 @@ describe('Soft Assertions', () => {
213219
214220 } )
215221
222+ describe ( 'expect.soft with multiple elements' , ( ) => {
223+
224+ let elements : ChainablePromiseArray
225+
226+ beforeEach ( async ( ) => {
227+ elements = $$ ( 'sel' )
228+
229+ vi . mocked ( elements [ 0 ] . getText ) . mockResolvedValue ( 'Actual Text 0' )
230+ vi . mocked ( elements [ 1 ] . getText ) . mockResolvedValue ( 'Actual Text 1' )
231+
232+ expectWdio . clearSoftFailures ( )
233+ } )
234+
235+ it ( 'should not throw immediately on failure' , async ( ) => {
236+ const softService = SoftAssertService . getInstance ( )
237+ softService . setCurrentTest ( 'multiple-elements-test-1' , 'test name' , 'test file' )
238+
239+ await expectWdio . soft ( await elements ) . toHaveText ( 'Expected Text' , { wait : 0 } )
240+
241+ // Verify the failure was recorded
242+ const failures = expectWdio . getSoftFailures ( )
243+ expect ( failures . length ) . toBe ( 1 )
244+ expect ( failures [ 0 ] . matcherName ) . toBe ( 'toHaveText' )
245+ expect ( failures [ 0 ] . error . message ) . toEqual ( `\
246+ Expect $$(\`sel\`) to have text
247+
248+ - Expected - 1
249+ + Received + 2
250+
251+ Array [
252+ - "Expected Text",
253+ + "Actual Text 0",
254+ + "Actual Text 1",
255+ ]`
256+ )
257+ } )
258+ } )
259+
216260 describe ( 'SoftAssertService hooks' , ( ) => {
217261 it ( 'afterTest should throw if soft failures exist' , ( ) => {
218262 const softService = SoftAssertService . getInstance ( )
0 commit comments