@@ -10,14 +10,14 @@ import {
10
10
ComponentHarness ,
11
11
ComponentHarnessConstructor ,
12
12
HarnessPredicate ,
13
+ TestElement ,
13
14
} from '@angular/cdk/testing' ;
14
15
import { TooltipHarnessFilters } from './tooltip-harness-filters' ;
15
16
16
17
/** Harness for interacting with a mat-tooltip in tests. */
17
18
export class MatTooltipHarness extends ComponentHarness {
18
19
static hostSelector = '.mat-mdc-tooltip-trigger' ;
19
20
20
- private _optionalPanel = this . documentRootLocatorFactory ( ) . locatorForOptional ( '.mat-mdc-tooltip' ) ;
21
21
private _hiddenClass = 'mat-mdc-tooltip-hide' ;
22
22
private _disabledClass = 'mat-mdc-tooltip-disabled' ;
23
23
private _showAnimationName = 'mat-mdc-tooltip-show' ;
@@ -45,7 +45,7 @@ export class MatTooltipHarness extends ComponentHarness {
45
45
// element has ripples.
46
46
await host . dispatchEvent ( 'touchstart' , { changedTouches : [ ] } ) ;
47
47
await host . hover ( ) ;
48
- const panel = await this . _optionalPanel ( ) ;
48
+ const panel = await this . _getPanel ( ) ;
49
49
await panel ?. dispatchEvent ( 'animationend' , { animationName : this . _showAnimationName } ) ;
50
50
}
51
51
@@ -57,13 +57,13 @@ export class MatTooltipHarness extends ComponentHarness {
57
57
// the tooltip binds different events depending on the device.
58
58
await host . dispatchEvent ( 'touchend' ) ;
59
59
await host . mouseAway ( ) ;
60
- const panel = await this . _optionalPanel ( ) ;
60
+ const panel = await this . _getPanel ( ) ;
61
61
await panel ?. dispatchEvent ( 'animationend' , { animationName : this . _hideAnimationName } ) ;
62
62
}
63
63
64
64
/** Gets whether the tooltip is open. */
65
65
async isOpen ( ) : Promise < boolean > {
66
- const panel = await this . _optionalPanel ( ) ;
66
+ const panel = await this . _getPanel ( ) ;
67
67
return ! ! panel && ! ( await panel . hasClass ( this . _hiddenClass ) ) ;
68
68
}
69
69
@@ -75,7 +75,32 @@ export class MatTooltipHarness extends ComponentHarness {
75
75
76
76
/** Gets a promise for the tooltip panel's text. */
77
77
async getTooltipText ( ) : Promise < string > {
78
- const panel = await this . _optionalPanel ( ) ;
79
- return panel ? panel . text ( ) : '' ;
78
+ let textContainer : TestElement | null = await this . _getPanel ( ) ;
79
+
80
+ // Prior to #26779 the tooltip text was being read from any currently-open tooltip.
81
+ // Fixing the issue revealed lots of cases internally that were reading the text from
82
+ // stale tooltips that were retained between tests. As a fallback for such cases, we
83
+ // fall back to reading the text through `aria-describedby`.
84
+ if ( textContainer === null ) {
85
+ const ariaDescribedBy = await ( await this . host ( ) ) . getAttribute ( 'aria-describedby' ) ;
86
+ const locatorFactory = this . documentRootLocatorFactory ( ) ;
87
+
88
+ if ( ariaDescribedBy !== null ) {
89
+ const spaceIndex = ariaDescribedBy . indexOf ( ' ' ) ;
90
+ const firstIdEnd = spaceIndex === - 1 ? ariaDescribedBy . length : spaceIndex ;
91
+ textContainer = await locatorFactory . locatorForOptional (
92
+ `#${ ariaDescribedBy . slice ( 0 , firstIdEnd ) } ` ,
93
+ ) ( ) ;
94
+ }
95
+ }
96
+
97
+ return textContainer ? textContainer . text ( ) : '' ;
98
+ }
99
+
100
+ /** Gets the tooltip panel associated with the trigger. */
101
+ private async _getPanel ( ) : Promise < TestElement | null > {
102
+ const host = await this . host ( ) ;
103
+ const locatorFactory = this . documentRootLocatorFactory ( ) ;
104
+ return locatorFactory . locatorForOptional ( `#${ await host . getAttribute ( 'data-mat-tooltip' ) } ` ) ( ) ;
80
105
}
81
106
}
0 commit comments