diff --git a/packages/playwright-ct-react/register.mjs b/packages/playwright-ct-react/register.mjs
index c8f13440a2..0c40e0a609 100644
--- a/packages/playwright-ct-react/register.mjs
+++ b/packages/playwright-ct-react/register.mjs
@@ -30,6 +30,10 @@ function render(component) {
if (typeof child === 'string')
return child;
return render(child);
+ }).filter(child => {
+ if (typeof child === 'string')
+ return !!child.trim();
+ return true;
}));
}
diff --git a/packages/trace-viewer/src/ui/networkResourceDetails.tsx b/packages/trace-viewer/src/ui/networkResourceDetails.tsx
index 18d58fccbd..7e99133146 100644
--- a/packages/trace-viewer/src/ui/networkResourceDetails.tsx
+++ b/packages/trace-viewer/src/ui/networkResourceDetails.tsx
@@ -125,7 +125,7 @@ export const NetworkResourceDetails: React.FunctionComponent<{
return
setExpanded(!expanded)} />
{title}
- { expanded &&
{body}
}
+ { expanded &&
{children}
}
;
};
diff --git a/packages/web/src/components/index.ts b/packages/web/src/components/index.ts
index a992912f29..1d76695673 100644
--- a/packages/web/src/components/index.ts
+++ b/packages/web/src/components/index.ts
@@ -14,11 +14,16 @@
* limitations under the License.
*/
+import { Expandable } from './expandable';
import { Source } from './source';
+import { SplitView } from './splitView';
import '../common.css';
+import '../third_party/vscode/codicon.css';
import register from '@playwright/experimental-ct-react/register';
register({
+ Expandable,
Source,
+ SplitView,
});
diff --git a/packages/web/src/components/splitView.spec.tsx b/packages/web/src/components/splitView.spec.tsx
new file mode 100644
index 0000000000..8e5b30bae5
--- /dev/null
+++ b/packages/web/src/components/splitView.spec.tsx
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { expect, test } from '@playwright/experimental-ct-react/test';
+import { SplitView } from './splitView';
+
+test.use({ viewport: { width: 500, height: 500 } });
+
+test('should render', async ({ mount }) => {
+ const component = await mount(
+ main
+
+ );
+ const mainBox = await component.locator('#main').boundingBox();
+ const sidebarBox = await component.locator('#sidebar').boundingBox();
+ expect.soft(mainBox).toEqual({ x: 0, y: 0, width: 500, height: 400 });
+ expect.soft(sidebarBox).toEqual({ x: 0, y: 401, width: 500, height: 99 });
+});
+
+test('should render sidebar first', async ({ mount }) => {
+ const component = await mount(
+ main
+
+ );
+ const mainBox = await component.locator('#main').boundingBox();
+ const sidebarBox = await component.locator('#sidebar').boundingBox();
+ expect.soft(mainBox).toEqual({ x: 0, y: 100, width: 500, height: 400 });
+ expect.soft(sidebarBox).toEqual({ x: 0, y: 0, width: 500, height: 99 });
+});
+
+test('should render horizontal split', async ({ mount }) => {
+ const component = await mount(
+ main
+
+ );
+ const mainBox = await component.locator('#main').boundingBox();
+ const sidebarBox = await component.locator('#sidebar').boundingBox();
+ expect.soft(mainBox).toEqual({ x: 100, y: 0, width: 400, height: 500 });
+ expect.soft(sidebarBox).toEqual({ x: 0, y: 0, width: 99, height: 500 });
+});
+
+test('should hide sidebar', async ({ mount }) => {
+ const component = await mount(
+ main
+
+ );
+ const mainBox = await component.locator('#main').boundingBox();
+ expect.soft(mainBox).toEqual({ x: 0, y: 0, width: 500, height: 500 });
+});
+
+test('drag resize', async ({ page, mount }) => {
+ const component = await mount(
+ main
+
+ );
+ await page.mouse.move(25, 400);
+ await page.mouse.down();
+ await page.mouse.move(25, 100);
+ await page.mouse.up();
+ const mainBox = await component.locator('#main').boundingBox();
+ const sidebarBox = await component.locator('#sidebar').boundingBox();
+ expect.soft(mainBox).toEqual({ x: 0, y: 0, width: 500, height: 100 });
+ expect.soft(sidebarBox).toEqual({ x: 0, y: 101, width: 500, height: 399 });
+});