|
1 | 1 | import {ComponentPortal, PortalModule} from '@angular/cdk/portal';
|
2 | 2 | import {CdkScrollable, ScrollingModule, ViewportRuler} from '@angular/cdk/scrolling';
|
3 |
| -import {MockNgZone} from '@angular/cdk/testing/private'; |
| 3 | +import {dispatchFakeEvent, MockNgZone} from '@angular/cdk/testing/private'; |
4 | 4 | import {Component, ElementRef, NgModule, NgZone} from '@angular/core';
|
5 |
| -import {inject, TestBed} from '@angular/core/testing'; |
| 5 | +import {fakeAsync, inject, TestBed, tick} from '@angular/core/testing'; |
6 | 6 | import {Subscription} from 'rxjs';
|
7 | 7 | import {map} from 'rxjs/operators';
|
8 | 8 | import {
|
@@ -2194,7 +2194,51 @@ describe('FlexibleConnectedPositionStrategy', () => {
|
2194 | 2194 | expect(Math.floor(overlayRect.width)).toBe(rightOffset);
|
2195 | 2195 | });
|
2196 | 2196 |
|
| 2197 | + it('should account for sub-pixel deviations in the size of the overlay', fakeAsync(() => { |
| 2198 | + originElement.style.top = '200px'; |
| 2199 | + originElement.style.left = '200px'; |
| 2200 | + |
| 2201 | + positionStrategy |
| 2202 | + .withFlexibleDimensions() |
| 2203 | + .withPositions([{ |
| 2204 | + originX: 'start', |
| 2205 | + originY: 'bottom', |
| 2206 | + overlayX: 'start', |
| 2207 | + overlayY: 'top' |
| 2208 | + }]); |
| 2209 | + |
| 2210 | + attachOverlay({ |
| 2211 | + positionStrategy, |
| 2212 | + height: '100%' |
| 2213 | + }); |
2197 | 2214 |
|
| 2215 | + const originalGetBoundingClientRect = overlayRef.overlayElement.getBoundingClientRect; |
| 2216 | + |
| 2217 | + // The browser may return a `ClientRect` with sub-pixel deviations if the screen is zoomed in. |
| 2218 | + // Since there's no way for us to zoom in the screen programmatically, we simulate the effect |
| 2219 | + // by patching `getBoundingClientRect` to return a slightly different value. |
| 2220 | + overlayRef.overlayElement.getBoundingClientRect = function() { |
| 2221 | + const clientRect = originalGetBoundingClientRect.apply(this); |
| 2222 | + const zoomOffset = 0.1; |
| 2223 | + |
| 2224 | + return { |
| 2225 | + top: clientRect.top, |
| 2226 | + right: clientRect.right + zoomOffset, |
| 2227 | + bottom: clientRect.bottom + zoomOffset, |
| 2228 | + left: clientRect.left, |
| 2229 | + width: clientRect.width + zoomOffset, |
| 2230 | + height: clientRect.height + zoomOffset |
| 2231 | + } as any; |
| 2232 | + }; |
| 2233 | + |
| 2234 | + // Trigger a resize so that the overlay get repositioned from scratch |
| 2235 | + // and to have it use the patched `getBoundingClientRect`. |
| 2236 | + dispatchFakeEvent(window, 'resize'); |
| 2237 | + tick(100); // The resize listener is usually debounced. |
| 2238 | + |
| 2239 | + const overlayRect = originalGetBoundingClientRect.apply(overlayRef.overlayElement); |
| 2240 | + expect(Math.floor(overlayRect.top)).toBe(0); |
| 2241 | + })); |
2198 | 2242 |
|
2199 | 2243 | });
|
2200 | 2244 |
|
|
0 commit comments