blob: 6c214419c904d149d0a540493311846392351d56 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;
import '../../common/test_initialization.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
void testMain() {
setUpAll(() async {
await bootstrapAndRunApp();
});
group('PlatformViewManager', () {
const String viewType = 'forTest';
const int viewId = 6;
late PlatformViewManager contentManager;
setUp(() {
contentManager = PlatformViewManager();
});
group('knowsViewType', () {
test('recognizes viewTypes after registering them', () async {
expect(contentManager.knowsViewType(viewType), isFalse);
contentManager.registerFactory(viewType, (int id) => createDomHTMLDivElement());
expect(contentManager.knowsViewType(viewType), isTrue);
});
});
group('knowsViewId', () {
test('recognizes viewIds after *rendering* them', () async {
expect(contentManager.knowsViewId(viewId), isFalse);
contentManager.registerFactory(viewType, (int id) => createDomHTMLDivElement());
expect(contentManager.knowsViewId(viewId), isFalse);
contentManager.renderContent(viewType, viewId, null);
expect(contentManager.knowsViewId(viewId), isTrue);
});
test('forgets viewIds after clearing them', () {
contentManager.registerFactory(viewType, (int id) => createDomHTMLDivElement());
final DomElement view = contentManager.renderContent(viewType, viewId, null);
expect(contentManager.knowsViewId(viewId), isTrue);
contentManager.clearPlatformView(viewId);
expect(contentManager.knowsViewId(viewId), isFalse);
expect(view.parentNode, isNull);
});
});
group('registerFactory', () {
test('does NOT re-register factories', () async {
contentManager.registerFactory(
viewType, (int id) => createDomHTMLDivElement()..id = 'pass');
// this should be rejected
contentManager.registerFactory(
viewType, (int id) => createDomHTMLSpanElement()..id = 'fail');
final DomElement contents =
contentManager.renderContent(viewType, viewId, null);
expect(contents.querySelector('#pass'), isNotNull);
expect(contents.querySelector('#fail'), isNull,
reason: 'Factories cannot be overridden once registered');
});
});
group('renderContent', () {
const String unregisteredViewType = 'unregisteredForTest';
const String anotherViewType = 'anotherViewType';
setUp(() {
contentManager.registerFactory(viewType, (int id) {
return createDomHTMLDivElement()..setAttribute('data-viewId', '$id');
});
contentManager.registerFactory(anotherViewType, (int id) {
return createDomHTMLDivElement()
..setAttribute('data-viewId', '$id')
..style.height = 'auto'
..style.width = '55%';
});
});
test('refuse to render views for unregistered factories', () async {
expect(
() => contentManager.renderContent(unregisteredViewType, viewId, null),
throwsA(const TypeMatcher<AssertionError>().having(
(AssertionError error) => error.message,
'assertion message',
contains(unregisteredViewType),
)),
);
});
test('rendered markup contains required attributes', () async {
final DomElement content =
contentManager.renderContent(viewType, viewId, null);
expect(content.getAttribute('slot'), getPlatformViewSlotName(viewId));
expect(content.getAttribute('id'), getPlatformViewDomId(viewId));
final DomElement userContent = content.querySelector('div')!;
expect(userContent.style.height, '100%');
expect(userContent.style.width, '100%');
});
test('slot property has the same value as createPlatformViewSlot', () async {
final DomElement content =
contentManager.renderContent(viewType, viewId, null);
final DomElement slot = createPlatformViewSlot(viewId);
final DomElement innerSlot = slot.querySelector('slot')!;
expect(content.getAttribute('slot'), innerSlot.getAttribute('name'),
reason:
'The slot attribute of the rendered content must match the name attribute of the SLOT of a given viewId');
});
test('do not modify style.height / style.width if passed by the user (anotherViewType)',
() async {
final DomElement content =
contentManager.renderContent(anotherViewType, viewId, null);
final DomElement userContent = content.querySelector('div')!;
expect(userContent.style.height, 'auto');
expect(userContent.style.width, '55%');
});
test('returns cached instances of already-rendered content', () async {
final DomElement firstRender =
contentManager.renderContent(viewType, viewId, null);
final DomElement anotherRender =
contentManager.renderContent(viewType, viewId, null);
expect(firstRender, same(anotherRender));
});
});
group('getViewById', () {
test('finds created views', () async {
final Map<int, DomElement> views1 = <int, DomElement>{
1: createDomHTMLDivElement(),
2: createDomHTMLDivElement(),
5: createDomHTMLDivElement(),
};
final Map<int, DomElement> views2 = <int, DomElement>{
3: createDomHTMLDivElement(),
4: createDomHTMLDivElement(),
};
contentManager.registerFactory('forTest1', (int id) => views1[id]!);
contentManager.registerFactory('forTest2', (int id) => views2[id]!);
// Render all 5 views.
for (final int id in views1.keys) {
contentManager.renderContent('forTest1', id, null);
}
for (final int id in views2.keys) {
contentManager.renderContent('forTest2', id, null);
}
// Check all 5 views.
for (final int id in views1.keys) {
expect(contentManager.getViewById(id), views1[id]);
}
for (final int id in views2.keys) {
expect(contentManager.getViewById(id), views2[id]);
}
// Throws for unknown viewId.
expect(() {
contentManager.getViewById(99);
}, throwsA(isA<AssertionError>()));
});
test('throws if view has been cleared', () {
final DomHTMLDivElement view = createDomHTMLDivElement();
contentManager.registerFactory(viewType, (int id) => view);
// Throws before viewId is rendered.
expect(() {
contentManager.getViewById(viewId);
}, throwsA(isA<AssertionError>()));
contentManager.renderContent(viewType, viewId, null);
// Succeeds after viewId is rendered.
expect(contentManager.getViewById(viewId), view);
contentManager.clearPlatformView(viewId);
// Throws after viewId is cleared.
expect(() {
contentManager.getViewById(viewId);
}, throwsA(isA<AssertionError>()));
});
});
test('default factories', () {
final DomElement content0 = contentManager.renderContent(
ui_web.PlatformViewRegistry.defaultVisibleViewType,
viewId,
<dynamic, dynamic>{'tagName': 'table'},
);
expect(
contentManager.getViewById(viewId),
content0.querySelector('table'),
);
expect(contentManager.isVisible(viewId), isTrue);
expect(contentManager.isInvisible(viewId), isFalse);
final DomElement content1 = contentManager.renderContent(
ui_web.PlatformViewRegistry.defaultInvisibleViewType,
viewId + 1,
<dynamic, dynamic>{'tagName': 'script'},
);
expect(
contentManager.getViewById(viewId + 1),
content1.querySelector('script'),
);
expect(contentManager.isVisible(viewId + 1), isFalse);
expect(contentManager.isInvisible(viewId + 1), isTrue);
final DomElement content2 = contentManager.renderContent(
ui_web.PlatformViewRegistry.defaultVisibleViewType,
viewId + 2,
<dynamic, dynamic>{'tagName': 'p'},
);
expect(
contentManager.getViewById(viewId + 2),
content2.querySelector('p'),
);
expect(contentManager.isVisible(viewId + 2), isTrue);
expect(contentManager.isInvisible(viewId + 2), isFalse);
});
});
}