diff --git a/npm/react/cypress/component/viewport-spec.js b/npm/react/cypress/component/viewport-spec.js
deleted file mode 100644
index 74ac9ec72ca4..000000000000
--- a/npm/react/cypress/component/viewport-spec.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const viewportWidth = 200
-const viewportHeight = 100
-
-describe('cypress.json viewport',
- { viewportWidth, viewportHeight },
- () => {
- it('should have the correct dimensions', () => {
- // cy.should cannot be the first cy command we run
- cy.window().should((w) => {
- expect(w.innerWidth).to.eq(viewportWidth)
- expect(w.innerHeight).to.eq(viewportHeight)
- })
- })
- })
-
-describe('cy.viewport', () => {
- it('should resize the viewport', () => {
- cy.viewport(viewportWidth, viewportHeight).should(() => {
- expect(window.innerWidth).to.eq(viewportWidth)
- expect(window.innerHeight).to.eq(viewportHeight)
- })
- })
-})
diff --git a/npm/react/cypress/component/viewport-spec.jsx b/npm/react/cypress/component/viewport-spec.jsx
new file mode 100644
index 000000000000..75d9702d6fb6
--- /dev/null
+++ b/npm/react/cypress/component/viewport-spec.jsx
@@ -0,0 +1,39 @@
+import React from 'react'
+import { mount } from '@cypress/react'
+
+const viewportWidth = 200
+const viewportHeight = 100
+
+describe('cypress.json viewport',
+ { viewportWidth, viewportHeight },
+ () => {
+ it('should have the correct dimensions', () => {
+ // cy.should cannot be the first cy command we run
+ cy.window().should((w) => {
+ expect(w.innerWidth).to.eq(viewportWidth)
+ expect(w.innerHeight).to.eq(viewportHeight)
+ })
+ })
+ })
+
+describe('cy.viewport', () => {
+ it('should resize the viewport', () => {
+ cy.viewport(viewportWidth, viewportHeight).should(() => {
+ expect(window.innerWidth).to.eq(viewportWidth)
+ expect(window.innerHeight).to.eq(viewportHeight)
+ })
+ })
+
+ it('should make it scale down when overflowing', () => {
+ mount(
+ Lorem, ipsum dolor sit amet consectetur adipisicing elit.
+ Incidunt necessitatibus quia quo obcaecati tempora numquam nobis
+ minima libero vel? Nam sequi iusto quod fugit vel rerum eligendi beatae voluptatibus numquam.
+
)
+
+ expect(getComputedStyle(window.parent.document.querySelector('iframe').parentElement).transform).to.contain('matrix(1')
+ cy.viewport(2000, 200).should(() => {
+ expect(getComputedStyle(window.parent.document.querySelector('iframe').parentElement).transform).not.to.contain('matrix(1')
+ })
+ })
+})
diff --git a/packages/runner-ct/src/app/app.scss b/packages/runner-ct/src/app/app.scss
index a449fa51980a..366b51efad4a 100644
--- a/packages/runner-ct/src/app/app.scss
+++ b/packages/runner-ct/src/app/app.scss
@@ -73,7 +73,7 @@ main.app-ct {
}
.runner-ct {
- left: $specs-list-offset;
+ left: 0;
header {
position: static;
@@ -82,6 +82,9 @@ main.app-ct {
right: unset;
bottom: unset;
}
+ .size-container{
+ transform-origin: 0 0;
+ }
}
.ct-plugins {
diff --git a/packages/runner-ct/src/app/app.tsx b/packages/runner-ct/src/app/app.tsx
index a178f5aa0b5d..a49cedfd159d 100644
--- a/packages/runner-ct/src/app/app.tsx
+++ b/packages/runner-ct/src/app/app.tsx
@@ -25,12 +25,15 @@ export interface ExtendedConfigOptions extends Cypress.ConfigOptions {
}
interface AppProps {
- state: State;
- // eslint-disable-next-line
+ state: State
eventManager: typeof EventManager
config: ExtendedConfigOptions
}
+const DEFAULT_LEFT_SIDE_OF_SPLITPANE_WIDTH = 355
+// needs to account for the left bar + the margins around the viewport
+const VIEWPORT_SIDE_MARGIN = 40 + 17
+
const App: React.FC = observer(
function App (props: AppProps) {
const pluginRootContainer = React.useRef(null)
@@ -40,13 +43,46 @@ const App: React.FC = observer(
const [pluginsHeight, setPluginsHeight] = React.useState(500)
const [isResizing, setIsResizing] = React.useState(false)
const [isSpecsListOpen, setIsSpecsListOpen] = React.useState(true)
+ const [leftSideOfSplitPaneWidth, setLeftSideOfSplitPaneWidth] = React.useState(DEFAULT_LEFT_SIDE_OF_SPLITPANE_WIDTH)
+ const headerRef = React.useRef(null)
+
+ function monitorWindowResize () {
+ // I can't use forwardref in class based components
+ // Header still is a class component
+ // FIXME: use a forwardRef when available
+ const header = headerRef.current.headerRef
+
+ function onWindowResize () {
+ state.updateWindowDimensions({
+ windowWidth: window.innerWidth,
+ windowHeight: window.innerHeight,
+ reporterWidth: leftSideOfSplitPaneWidth + VIEWPORT_SIDE_MARGIN,
+ headerHeight: header.offsetHeight || 0,
+ })
+ }
+
+ window.addEventListener('resize', onWindowResize)
+ window.dispatchEvent(new Event('resize'))
+ }
React.useEffect(() => {
if (pluginRootContainer.current) {
state.initializePlugins(config, pluginRootContainer.current)
}
+
+ monitorWindowResize()
}, [])
+ function onSplitPaneChange (newWidth: number) {
+ setLeftSideOfSplitPaneWidth(newWidth)
+ state.updateWindowDimensions({
+ reporterWidth: newWidth + VIEWPORT_SIDE_MARGIN,
+ windowWidth: null,
+ windowHeight: null,
+ headerHeight: null,
+ })
+ }
+
return (
<>
@@ -73,6 +109,7 @@ const App: React.FC = observer(
defaultSize={355}
onDragStarted={() => setIsResizing(true)}
onDragFinished={() => setIsResizing(false)}
+ onChange={onSplitPaneChange}
className={cs('reporter-pane', { 'is-reporter-resizing': isResizing })}
>
@@ -105,7 +142,7 @@ const App: React.FC
= observer(
}
>
-
+
diff --git a/packages/runner-ct/src/header/header.jsx b/packages/runner-ct/src/header/header.jsx
index c0e55cfd6fe8..ae9b9e71b182 100644
--- a/packages/runner-ct/src/header/header.jsx
+++ b/packages/runner-ct/src/header/header.jsx
@@ -12,14 +12,16 @@ import selectorPlaygroundModel from '../selector-playground/selector-playground-
@observer
export default class Header extends Component {
- @observable showingViewportMenu = false
+ headerRef = React.createRef()
+
+ @observable showingViewportMenu = false;
render () {
const { state, config } = this.props
return (
@@ -36,6 +36,7 @@ export default class Iframes extends Component {
style={{
height,
width,
+ transform: `scale(${scale})`,
}}
/>
diff --git a/packages/runner-ct/src/iframe/iframes.scss b/packages/runner-ct/src/iframe/iframes.scss
index 9529c5b27b46..711c29cb0cc3 100644
--- a/packages/runner-ct/src/iframe/iframes.scss
+++ b/packages/runner-ct/src/iframe/iframes.scss
@@ -1,9 +1,3 @@
-$cypress_blue: #3380FF;
-$hairline-color: $cypress_blue;
-$hairline-thickness: 1px;
-$hairline-size: min(60px, 80%);
-$hairline-offset: 15px;
-
.iframes-ct-container {
margin: 8px;
}
@@ -11,31 +5,8 @@ $hairline-offset: 15px;
.size-container {
width: 100%;
overflow: auto;
- resize: both;
background: none;
box-shadow: none;
-
- &:after, &:before {
- content: "";
- position: absolute;
- background: $hairline-color;
- opacity: .5;
- padding: -2px;
- }
-
- &:after {
- height: $hairline-size;
- width: $hairline-thickness;
- right: 0;
- bottom: $hairline-offset;
- }
-
- &:before {
- width: $hairline-size;
- height: $hairline-thickness;
- right: $hairline-offset;
- bottom: 0;
- }
}
.app-ct .runner {
diff --git a/packages/runner-ct/src/lib/state.ts b/packages/runner-ct/src/lib/state.ts
index f06452f860b3..da56b86d6cd2 100644
--- a/packages/runner-ct/src/lib/state.ts
+++ b/packages/runner-ct/src/lib/state.ts
@@ -163,7 +163,15 @@ export default class State {
}
}
- @action updateWindowDimensions ({ windowWidth, windowHeight, reporterWidth, headerHeight }) {
+ @action updateWindowDimensions ({
+ windowWidth, windowHeight, reporterWidth, headerHeight,
+ }:
+ {
+ windowWidth: number | null
+ windowHeight: number | null
+ reporterWidth: number | null
+ headerHeight: number | null
+ }) {
if (windowWidth != null) this.windowWidth = windowWidth
if (windowHeight != null) this.windowHeight = windowHeight