Skip to content

Commit

Permalink
fix: fix selector-playground css (cypress-io#4940)
Browse files Browse the repository at this point in the history
* fix selector-playground css

* add selector_playground e2e spec

* add notes to webpack import syntax

* add notes to test

* fix runner unit tests: handle webpack imports
  • Loading branch information
kuceb authored and grabartley committed Oct 6, 2019
1 parent 3d8def9 commit b033189
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
describe('selector_playground', () => {

it('draws rect over currently hovered element', () => {
cy.visit('/fixtures/dom.html')
.then(() => {

// We trick the selector-playground into rendering while the test is running
top.Runner.configureMobx({ enforceActions: 'never' })
top.Runner.state.isRunning = false

const $highlightBtn = cy.$$('button.highlight-toggle:visible', top.document)

if (!$highlightBtn.length) {
const $btn = cy.$$('button.selector-playground-toggle', top.document)

$btn.click()
} else {
if (!$highlightBtn.hasClass('active')) {
$highlightBtn.click()
}
}

cy.get('input:first')
.trigger('mousemove', { force: true })
.should(expectToBeCovered)

})
})
})

/**
*
* @param {JQuery<HTMLElement>} $el
*/
const expectToBeCovered = ($el) => {
const el = $el[0]
const rect = el.getBoundingClientRect()

const elAtPoint = el.ownerDocument.elementFromPoint(rect.left, rect.top)

expect(el).not.eq(elAtPoint)
}
100 changes: 44 additions & 56 deletions packages/runner/src/lib/dom.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import _ from 'lodash'
import { $ } from '@packages/driver'
import Promise from 'bluebird'

import { $ } from '@packages/driver'
import selectorPlaygroundHighlight from '../selector-playground/highlight'
// The '!' tells webpack to disable normal loaders, and keep loaders with `enforce: 'pre'` and `enforce: 'post'`
// This disables the CSSExtractWebpackPlugin and allows us to get the CSS as a raw string instead of saving it to a separate file.
import selectorPlaygroundCSS from '!../selector-playground/selector-playground.scss'

const styles = (styleString) => {
return styleString.replace(/\s*\n\s*/g, '')
Expand Down Expand Up @@ -141,11 +143,11 @@ function getOrCreateSelectorHelperDom ($body) {
if ($container.length) {
const shadowRoot = $container[0].shadowRoot

return Promise.resolve({
return {
$container,
shadowRoot,
$reactContainer: $(shadowRoot).find('.react-container'),
})
}
}

$container = $('<div />')
Expand All @@ -159,66 +161,52 @@ function getOrCreateSelectorHelperDom ($body) {
.addClass('react-container')
.appendTo(shadowRoot)

return Promise.try(() => {
return fetch('/__cypress/runner/cypress_selector_playground.css')
})
.then((result) => {
return result.text()
})
.then((content) => {
$('<style />', { html: content }).prependTo(shadowRoot)

return { $container, shadowRoot, $reactContainer }
})
.catch((error) => {
console.error('Selector playground failed to load styles:', error) // eslint-disable-line no-console
$('<style />', { html: selectorPlaygroundCSS.toString() }).prependTo(shadowRoot)

return { $container, shadowRoot, $reactContainer }
})
return { $container, shadowRoot, $reactContainer }
}

function addOrUpdateSelectorPlaygroundHighlight ({ $el, $body, selector, showTooltip, onClick }) {
getOrCreateSelectorHelperDom($body)
.then(({ $container, shadowRoot, $reactContainer }) => {
if (!$el) {
selectorPlaygroundHighlight.unmount($reactContainer[0])
$reactContainer.off('click')
$container.remove()

return
}
const { $container, shadowRoot, $reactContainer } = getOrCreateSelectorHelperDom($body)

const borderSize = 2

const styles = $el.map((__, el) => {
const $el = $(el)
const offset = $el.offset()

return {
position: 'absolute',
margin: 0,
padding: 0,
width: $el.outerWidth(),
height: $el.outerHeight(),
top: offset.top - borderSize,
left: offset.left - borderSize,
transform: $el.css('transform'),
zIndex: getZIndex($el),
}
}).get()
if (!$el) {
selectorPlaygroundHighlight.unmount($reactContainer[0])
$reactContainer.off('click')
$container.remove()

return
}

const borderSize = 2

if ($el.length === 1) {
$reactContainer
.off('click')
.on('click', onClick)
const styles = $el.map((__, el) => {
const $el = $(el)
const offset = $el.offset()

return {
position: 'absolute',
margin: 0,
padding: 0,
width: $el.outerWidth(),
height: $el.outerHeight(),
top: offset.top - borderSize,
left: offset.left - borderSize,
transform: $el.css('transform'),
zIndex: getZIndex($el),
}
}).get()

selectorPlaygroundHighlight.render($reactContainer[0], {
selector,
appendTo: shadowRoot,
showTooltip,
styles,
})
if ($el.length === 1) {
$reactContainer
.off('click')
.on('click', onClick)
}

selectorPlaygroundHighlight.render($reactContainer[0], {
selector,
appendTo: shadowRoot,
showTooltip,
styles,
})
}

Expand Down
7 changes: 6 additions & 1 deletion packages/runner/src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ import Container from './app/container'

configure({ enforceActions: 'strict' })

window.Runner = {
const Runner = {
start (el, config) {
action('started', () => {
const state = new State((config.state || {}).reporterWidth)

Runner.state = state
Runner.configureMobx = configure

state.updateDimensions(config.viewportWidth, config.viewportHeight)

render(<Container config={config} state={state} />, el)
})()
},
}

window.Runner = Runner
16 changes: 15 additions & 1 deletion packages/web-config/node-jsdom-setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mockRequire from 'mock-require'
import { JSDOM } from 'jsdom'
import * as ansiEscapes from 'ansi-escapes'

declare global {
module NodeJS {
Expand Down Expand Up @@ -65,6 +66,7 @@ export const register = ({
Module._load = function (...args) {
let browserPkg = args

// Follow browser-field spec for importing modules
if (!['path'].includes(args[0])) {
try {
browserPkg = [bresolve.sync.apply(this, args)]
Expand All @@ -73,14 +75,26 @@ export const register = ({
}
}

return _load.apply(this, browserPkg)
// Stub out all webpack-specific imports
if (args[0].includes('!')) {
return {}
}

const ret = _load.apply(this, browserPkg)

return ret
}

}

overrideRequire()
}

// eslint-disable-next-line
after(() => {
process.stdout.write(ansiEscapes.cursorShow)
})

export const returnMockRequire = (name, modExport = {}) => {
mockRequire(name, modExport)

Expand Down
1 change: 1 addition & 0 deletions packages/web-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@types/copy-webpack-plugin": "5.0.0",
"@types/html-webpack-plugin": "3.2.0",
"@types/webpack": "4.4.25",
"ansi-escapes": "4.2.1",
"autoprefixer": "9.6.1",
"babel-loader": "8.0.5",
"browser-resolve": "1.11.3",
Expand Down
7 changes: 7 additions & 0 deletions packages/web-config/webpack.config.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ const config: webpack.Configuration = {
exclude: /node_modules/,
use: [
{ loader: MiniCSSExtractWebpackPlugin.loader },
],
},
{
test: /\.s?css$/,
exclude: /node_modules/,
enforce: 'pre',
use: [
{
loader: require.resolve('css-loader'),
options: {
Expand Down

0 comments on commit b033189

Please sign in to comment.