mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-23 23:49:43 -05:00
* Handle 0px tall elements with a better error message Closes #5149 Co-authored-by: Minh Nguyen <minhnguyenxx@gmail.com> Co-authored-by: Jennifer Shehane <shehane.jennifer@gmail.com> * Add padding support to element#screenshot Closes #4440 Co-authored-by: Minh Nguyen <minhnguyenxx@gmail.com> Co-authored-by: Jennifer Shehane <shehane.jennifer@gmail.com> * add e2e tests
This commit is contained in:
committed by
Jennifer Shehane
parent
2944be19a0
commit
116a634a90
Vendored
+8
@@ -2189,11 +2189,19 @@ declare namespace Cypress {
|
||||
height: number
|
||||
}
|
||||
|
||||
type Padding =
|
||||
| number
|
||||
| [number]
|
||||
| [number, number]
|
||||
| [number, number, number]
|
||||
| [number, number, number, number]
|
||||
|
||||
interface ScreenshotOptions {
|
||||
blackout: string[]
|
||||
capture: 'runner' | 'viewport' | 'fullPage'
|
||||
clip: Dimensions
|
||||
disableTimersAndAnimations: boolean
|
||||
padding: Padding
|
||||
scale: boolean
|
||||
beforeScreenshot(doc: Document): void
|
||||
afterScreenshot(doc: Document): void
|
||||
|
||||
@@ -81,6 +81,12 @@ scrollOverrides = (win, doc) ->
|
||||
doc.body.style.overflowY = originalBodyOverflowY
|
||||
win.scrollTo(originalX, originalY)
|
||||
|
||||
validateNumScreenshots = (numScreenshots, automationOptions) ->
|
||||
if numScreenshots < 1
|
||||
$utils.throwErrByPath("screenshot.invalid_height", {
|
||||
log: automationOptions.log
|
||||
})
|
||||
|
||||
takeScrollingScreenshots = (scrolls, win, state, automationOptions) ->
|
||||
scrollAndTake = ({ y, clip, afterScroll }, index) ->
|
||||
win.scrollTo(0, y)
|
||||
@@ -108,6 +114,8 @@ takeFullPageScreenshot = (state, automationOptions) ->
|
||||
viewportHeight = getViewportHeight(state)
|
||||
numScreenshots = Math.ceil(docHeight / viewportHeight)
|
||||
|
||||
validateNumScreenshots(numScreenshots, automationOptions)
|
||||
|
||||
scrolls = _.map _.times(numScreenshots), (index) ->
|
||||
y = viewportHeight * index
|
||||
clip = if index + 1 is numScreenshots
|
||||
@@ -126,21 +134,48 @@ takeFullPageScreenshot = (state, automationOptions) ->
|
||||
takeScrollingScreenshots(scrolls, win, state, automationOptions)
|
||||
.finally(resetScrollOverrides)
|
||||
|
||||
applyPaddingToElementPositioning = (elPosition, automationOptions) ->
|
||||
if not automationOptions.padding
|
||||
return elPosition
|
||||
|
||||
[ paddingTop, paddingRight, paddingBottom, paddingLeft ] = automationOptions.padding
|
||||
|
||||
return {
|
||||
width: elPosition.width + paddingLeft + paddingRight
|
||||
height: elPosition.height + paddingTop + paddingBottom
|
||||
fromViewport: {
|
||||
top: elPosition.fromViewport.top - paddingTop
|
||||
left: elPosition.fromViewport.left - paddingLeft
|
||||
bottom: elPosition.fromViewport.bottom + paddingBottom
|
||||
}
|
||||
fromWindow: {
|
||||
top: elPosition.fromWindow.top - paddingTop
|
||||
}
|
||||
}
|
||||
|
||||
takeElementScreenshot = ($el, state, automationOptions) ->
|
||||
win = state("window")
|
||||
doc = state("document")
|
||||
|
||||
resetScrollOverrides = scrollOverrides(win, doc)
|
||||
|
||||
elPosition = $dom.getElementPositioning($el)
|
||||
elPosition = applyPaddingToElementPositioning(
|
||||
$dom.getElementPositioning($el),
|
||||
automationOptions
|
||||
)
|
||||
viewportHeight = getViewportHeight(state)
|
||||
viewportWidth = getViewportWidth(state)
|
||||
numScreenshots = Math.ceil(elPosition.height / viewportHeight)
|
||||
|
||||
validateNumScreenshots(numScreenshots, automationOptions)
|
||||
|
||||
scrolls = _.map _.times(numScreenshots), (index) ->
|
||||
y = elPosition.fromWindow.top + (viewportHeight * index)
|
||||
afterScroll = ->
|
||||
elPosition = $dom.getElementPositioning($el)
|
||||
elPosition = applyPaddingToElementPositioning(
|
||||
$dom.getElementPositioning($el),
|
||||
automationOptions
|
||||
)
|
||||
x = Math.min(viewportWidth, elPosition.fromViewport.left)
|
||||
width = Math.min(viewportWidth - x, elPosition.width)
|
||||
|
||||
@@ -188,6 +223,7 @@ getBlackout = ({ capture, blackout }) ->
|
||||
takeScreenshot = (Cypress, state, screenshotConfig, options = {}) ->
|
||||
{
|
||||
capture
|
||||
padding
|
||||
clip
|
||||
disableTimersAndAnimations
|
||||
onBeforeScreenshot
|
||||
@@ -236,6 +272,7 @@ takeScreenshot = (Cypress, state, screenshotConfig, options = {}) ->
|
||||
width: getViewportWidth(state)
|
||||
height: getViewportHeight(state)
|
||||
}
|
||||
padding
|
||||
userClip: clip
|
||||
viewport: {
|
||||
width: window.innerWidth
|
||||
@@ -313,7 +350,7 @@ module.exports = (Commands, Cypress, cy, state, config) ->
|
||||
|
||||
isWin = $dom.isWindow(subject)
|
||||
|
||||
screenshotConfig = _.pick(options, "capture", "scale", "disableTimersAndAnimations", "blackout", "waitForCommandSynchronization", "clip", "onBeforeScreenshot", "onAfterScreenshot")
|
||||
screenshotConfig = _.pick(options, "capture", "scale", "disableTimersAndAnimations", "blackout", "waitForCommandSynchronization", "padding", "clip", "onBeforeScreenshot", "onAfterScreenshot")
|
||||
screenshotConfig = $Screenshot.validate(screenshotConfig, "cy.screenshot", options._log)
|
||||
screenshotConfig = _.extend($Screenshot.getConfig(), screenshotConfig)
|
||||
|
||||
|
||||
@@ -780,7 +780,9 @@ module.exports = {
|
||||
invalid_capture: "{{cmd}}() 'capture' option must be one of the following: 'fullPage', 'viewport', or 'runner'. You passed: {{arg}}"
|
||||
invalid_boolean: "{{cmd}}() '{{option}}' option must be a boolean. You passed: {{arg}}"
|
||||
invalid_blackout: "{{cmd}}() 'blackout' option must be an array of strings. You passed: {{arg}}"
|
||||
invalid_clip: "{{cmd}}() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: {{arg}}"
|
||||
invalid_clip: "{{cmd}}() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: {{arg}}"
|
||||
invalid_height: "#{cmd('screenshot')} only works with a screenshot area with a height greater than zero."
|
||||
invalid_padding: "{{cmd}}() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: {{arg}}"
|
||||
invalid_callback: "{{cmd}}() '{{callback}}' option must be a function. You passed: {{arg}}"
|
||||
multiple_elements: "#{cmd('screenshot')} only works for a single element. You attempted to screenshot {{numElements}} elements."
|
||||
timed_out: "#{cmd('screenshot')} timed out waiting '{{timeout}}ms' to complete."
|
||||
|
||||
@@ -16,6 +16,37 @@ defaults = reset()
|
||||
|
||||
validCaptures = ["fullPage", "viewport", "runner"]
|
||||
|
||||
normalizePadding = (padding) ->
|
||||
padding ||= 0
|
||||
|
||||
if _.isArray(padding)
|
||||
# CSS shorthand
|
||||
# See: https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties#Tricky_edge_cases
|
||||
switch padding.length
|
||||
when 1
|
||||
top = right = bottom = left = padding[0]
|
||||
when 2
|
||||
top = bottom = padding[0]
|
||||
right = left = padding[1]
|
||||
when 3
|
||||
top = padding[0]
|
||||
right = left = padding[1]
|
||||
bottom = padding[2]
|
||||
when 4
|
||||
top = padding[0]
|
||||
right = padding[1]
|
||||
bottom = padding[2]
|
||||
left = padding[3]
|
||||
else
|
||||
top = right = bottom = left = padding
|
||||
|
||||
return [
|
||||
top
|
||||
right
|
||||
bottom
|
||||
left
|
||||
]
|
||||
|
||||
validateAndSetBoolean = (props, values, cmd, log, option) ->
|
||||
value = props[option]
|
||||
if not value?
|
||||
@@ -94,6 +125,21 @@ validate = (props, cmd, log) ->
|
||||
|
||||
values.clip = clip
|
||||
|
||||
if padding = props.padding
|
||||
isShorthandPadding = (value) -> (
|
||||
(_.isArray(value) and
|
||||
value.length >= 1 and
|
||||
value.length <= 4 and
|
||||
_.every(value, _.isFinite))
|
||||
)
|
||||
if not (_.isFinite(padding) or isShorthandPadding(padding))
|
||||
$utils.throwErrByPath("screenshot.invalid_padding", {
|
||||
log: log
|
||||
args: { cmd: cmd, arg: $utils.stringify(padding) }
|
||||
})
|
||||
|
||||
values.padding = normalizePadding(padding)
|
||||
|
||||
validateAndSetCallback(props, values, cmd, log, "onBeforeScreenshot")
|
||||
validateAndSetCallback(props, values, cmd, log, "onAfterScreenshot")
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
border: solid 1px black;
|
||||
margin: 20px;
|
||||
}
|
||||
.empty-element {
|
||||
height: 0px;
|
||||
width: 0px;
|
||||
border: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
.short-element {
|
||||
height: 100px;
|
||||
margin-left: 40px;
|
||||
@@ -20,6 +26,8 @@
|
||||
}
|
||||
.tall-element {
|
||||
height: 320px;
|
||||
|
||||
background: linear-gradient(red, yellow, blue);
|
||||
}
|
||||
.multiple {
|
||||
border: none;
|
||||
@@ -28,6 +36,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="empty-element"></div>
|
||||
<div class="short-element"></div>
|
||||
<div class="tall-element"></div>
|
||||
<div class="multiple"></div>
|
||||
|
||||
@@ -4,6 +4,9 @@ _ = Cypress._
|
||||
Promise = Cypress.Promise
|
||||
Screenshot = Cypress.Screenshot
|
||||
|
||||
getViewportHeight = () ->
|
||||
Math.min(cy.state("viewportHeight"), $(cy.state("window")).height())
|
||||
|
||||
describe "src/cy/commands/screenshot", ->
|
||||
beforeEach ->
|
||||
cy.stub(Cypress, "automation").callThrough()
|
||||
@@ -132,7 +135,7 @@ describe "src/cy/commands/screenshot", ->
|
||||
.then ->
|
||||
expect(Cypress.automation).to.be.calledWith("take:screenshot")
|
||||
args = Cypress.automation.withArgs("take:screenshot").args[0][1]
|
||||
args = _.omit(args, "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
args = _.omit(args, "padding", "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
expect(args).to.eql({
|
||||
testId: runnable.id
|
||||
titles: [
|
||||
@@ -168,7 +171,7 @@ describe "src/cy/commands/screenshot", ->
|
||||
.then ->
|
||||
expect(Cypress.automation.withArgs("take:screenshot")).to.be.calledOnce
|
||||
args = Cypress.automation.withArgs("take:screenshot").args[0][1]
|
||||
args = _.omit(args, "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
args = _.omit(args, "padding", "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
expect(args).to.eql({
|
||||
testId: runnable.id
|
||||
titles: [
|
||||
@@ -201,7 +204,7 @@ describe "src/cy/commands/screenshot", ->
|
||||
.then ->
|
||||
expect(Cypress.automation).to.be.calledWith("take:screenshot")
|
||||
args = Cypress.automation.withArgs("take:screenshot").args[0][1]
|
||||
args = _.omit(args, "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
args = _.omit(args, "padding", "clip", "userClip", "viewport", "takenPaths", "startTime")
|
||||
expect(args).to.eql({
|
||||
testId: runnable.id
|
||||
titles: [
|
||||
@@ -516,18 +519,71 @@ describe "src/cy/commands/screenshot", ->
|
||||
expect(scrollTo.getCall(2).args.join(",")).to.equal("0,100")
|
||||
|
||||
it "sends the right clip values for elements that need scrolling", ->
|
||||
scrollTo = cy.spy(cy.state("window"), "scrollTo")
|
||||
|
||||
cy.get(".tall-element").screenshot()
|
||||
.then ->
|
||||
expect(scrollTo.getCall(0).args).to.eql([0, 140])
|
||||
|
||||
take = Cypress.automation.withArgs("take:screenshot")
|
||||
expect(take.args[0][1].clip).to.eql({ x: 20, y: 0, width: 560, height: 200 })
|
||||
expect(take.args[1][1].clip).to.eql({ x: 20, y: 60, width: 560, height: 120 })
|
||||
|
||||
it "sends the right clip values for elements that don't need scrolling", ->
|
||||
scrollTo = cy.spy(cy.state("window"), "scrollTo")
|
||||
|
||||
cy.get(".short-element").screenshot()
|
||||
.then ->
|
||||
# even though we don't need to scroll, the implementation behaviour is to
|
||||
# try to scroll until the element is at the top of the viewport.
|
||||
expect(scrollTo.getCall(0).args).to.eql([0, 20])
|
||||
|
||||
take = Cypress.automation.withArgs("take:screenshot")
|
||||
expect(take.args[0][1].clip).to.eql({ x: 40, y: 0, width: 200, height: 100 })
|
||||
|
||||
it "applies padding to clip values for elements that need scrolling", ->
|
||||
padding = 10
|
||||
|
||||
scrollTo = cy.spy(cy.state("window"), "scrollTo")
|
||||
|
||||
cy.get(".tall-element").screenshot({ padding })
|
||||
.then ->
|
||||
viewportHeight = getViewportHeight()
|
||||
expect(scrollTo.getCall(0).args).to.eql([0, 140 - padding])
|
||||
expect(scrollTo.getCall(1).args).to.eql([0, 140 + viewportHeight - padding ])
|
||||
|
||||
take = Cypress.automation.withArgs("take:screenshot")
|
||||
|
||||
expect(take.args[0][1].clip).to.eql({
|
||||
x: 20 - padding,
|
||||
y: 0,
|
||||
width: 560 + padding * 2,
|
||||
height: viewportHeight
|
||||
})
|
||||
expect(take.args[1][1].clip).to.eql({
|
||||
x: 20 - padding,
|
||||
y: 60 - padding,
|
||||
width: 560 + padding * 2,
|
||||
height: 120 + padding * 2
|
||||
})
|
||||
|
||||
it "applies padding to clip values for elements that don't need scrolling", ->
|
||||
padding = 10
|
||||
|
||||
scrollTo = cy.spy(cy.state("window"), "scrollTo")
|
||||
|
||||
cy.get(".short-element").screenshot({ padding })
|
||||
.then ->
|
||||
expect(scrollTo.getCall(0).args).to.eql([0, padding])
|
||||
|
||||
take = Cypress.automation.withArgs("take:screenshot")
|
||||
expect(take.args[0][1].clip).to.eql({
|
||||
x: 30,
|
||||
y: 0,
|
||||
width: 220,
|
||||
height: 120
|
||||
})
|
||||
|
||||
it "works with cy.within()", ->
|
||||
cy.get(".short-element").within ->
|
||||
cy.screenshot()
|
||||
@@ -647,20 +703,42 @@ describe "src/cy/commands/screenshot", ->
|
||||
@assertErrorMessage("cy.screenshot() 'blackout' option must be an array of strings. You passed: true", done)
|
||||
cy.screenshot({ blackout: [true] })
|
||||
|
||||
it "throws if there is a 0px tall element height", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() only works with a screenshot area with a height greater than zero.", done)
|
||||
cy.visit("/fixtures/screenshots.html")
|
||||
cy.get('.empty-element').screenshot()
|
||||
|
||||
it "throws if padding is not a number", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: 50px", done)
|
||||
cy.screenshot({ padding: '50px' })
|
||||
|
||||
it "throws if padding is not an array of numbers", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: bad, bad, bad, bad", done)
|
||||
cy.screenshot({ padding: ['bad', 'bad', 'bad', 'bad'] })
|
||||
|
||||
it "throws if padding is not an array with a length between 1 and 4", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: 20, 10, 20, 10, 50", done)
|
||||
cy.screenshot({ padding: [20, 10, 20, 10, 50] })
|
||||
|
||||
it "throws if padding is a large negative number that causes a 0px tall element height", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() only works with a screenshot area with a height greater than zero.", done)
|
||||
cy.visit("/fixtures/screenshots.html")
|
||||
cy.get('.tall-element').screenshot({ padding: -161 })
|
||||
|
||||
it "throws if clip is not an object", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: true", done)
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: true", done)
|
||||
cy.screenshot({ clip: true })
|
||||
|
||||
it "throws if clip is lacking proper keys", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: {x: 5}", done)
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: {x: 5}", done)
|
||||
cy.screenshot({ clip: { x: 5 } })
|
||||
|
||||
it "throws if clip has extraneous keys", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: Object{5}", done)
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: Object{5}", done)
|
||||
cy.screenshot({ clip: { width: 100, height: 100, x: 5, y: 5, foo: 10 } })
|
||||
|
||||
it "throws if clip has non-number values", (done) ->
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: Object{4}", done)
|
||||
@assertErrorMessage("cy.screenshot() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: Object{4}", done)
|
||||
cy.screenshot({ clip: { width: 100, height: 100, x: 5, y: "5" } })
|
||||
|
||||
it "throws if element capture with multiple elements", (done) ->
|
||||
|
||||
@@ -59,7 +59,31 @@ describe "src/cypress/screenshot", ->
|
||||
Screenshot.defaults({
|
||||
clip: { width: 200, height: 100, x: 0, y: 0 }
|
||||
})
|
||||
expect(Screenshot.getConfig().clip).to.eql({ width: 200, height: 100, x: 0, y:0 })
|
||||
expect(
|
||||
Screenshot.getConfig().clip
|
||||
).to.eql(
|
||||
{ width: 200, height: 100, x: 0, y:0 }
|
||||
)
|
||||
|
||||
it "sets and normalizes padding if specified", ->
|
||||
tests = [
|
||||
[ 50, [50, 50, 50, 50] ]
|
||||
[ [15], [15, 15, 15, 15] ]
|
||||
[ [30, 20], [30, 20, 30, 20] ]
|
||||
[ [10, 20, 30], [10, 20, 30, 20] ]
|
||||
[ [20, 10, 20, 10], [20, 10, 20, 10] ]
|
||||
]
|
||||
|
||||
for test in tests
|
||||
[ input, expected ] = test
|
||||
Screenshot.defaults({
|
||||
padding: input
|
||||
})
|
||||
expect(
|
||||
Screenshot.getConfig().padding
|
||||
).to.eql(
|
||||
expected
|
||||
)
|
||||
|
||||
it "sets onBeforeScreenshot if specified", ->
|
||||
onBeforeScreenshot = cy.stub()
|
||||
@@ -114,25 +138,31 @@ describe "src/cypress/screenshot", ->
|
||||
Screenshot.defaults({ blackout: [true] })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'blackout' option must be an array of strings. You passed: true")
|
||||
|
||||
it "throws if clip is not an object", ->
|
||||
it "throws if padding is not a number or an array of numbers with a length between 1 and 4", ->
|
||||
expect =>
|
||||
Screenshot.defaults({ clip: true })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: true")
|
||||
Screenshot.defaults({ padding: '50px' })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: 50px")
|
||||
expect =>
|
||||
Screenshot.defaults({ padding: ['bad', 'bad', 'bad', 'bad'] })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: bad, bad, bad, bad")
|
||||
expect =>
|
||||
Screenshot.defaults({ padding: [20, 10, 20, 10, 50] })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'padding' option must be either a number or an array of numbers with a maximum length of 4. You passed: 20, 10, 20, 10, 50")
|
||||
|
||||
it "throws if clip is lacking proper keys", ->
|
||||
expect =>
|
||||
Screenshot.defaults({ clip: { x: 5 } })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: {x: 5}")
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: {x: 5}")
|
||||
|
||||
it "throws if clip has extraneous keys", ->
|
||||
expect =>
|
||||
Screenshot.defaults({ clip: { width: 100, height: 100, x: 5, y: 5, foo: 10 } })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: Object{5}")
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: Object{5}")
|
||||
|
||||
it "throws if clip has non-number values", ->
|
||||
expect =>
|
||||
Screenshot.defaults({ clip: { width: 100, height: 100, x: 5, y: "5" } })
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object of with the keys { width, height, x, y } and number values. You passed: Object{4}")
|
||||
.to.throw("Cypress.Screenshot.defaults() 'clip' option must be an object with the keys { width, height, x, y } and number values. You passed: Object{4}")
|
||||
|
||||
it "throws if onBeforeScreenshot is not a function", ->
|
||||
expect =>
|
||||
|
||||
@@ -33,6 +33,8 @@ exports['e2e screenshots passes 1'] = `
|
||||
2) ensures unique paths when there's a non-named screenshot and a failure
|
||||
✓ properly resizes the AUT iframe
|
||||
- does not take a screenshot for a pending test
|
||||
✓ adds padding to element screenshot when specified
|
||||
✓ does not add padding to non-element screenshot
|
||||
clipping
|
||||
✓ can clip app screenshots
|
||||
✓ can clip runner screenshots
|
||||
@@ -48,7 +50,7 @@ exports['e2e screenshots passes 1'] = `
|
||||
✓ takes another screenshot
|
||||
|
||||
|
||||
18 passing
|
||||
20 passing
|
||||
1 pending
|
||||
5 failing
|
||||
|
||||
@@ -84,12 +86,12 @@ Because this error occurred during a 'after each' hook we are skipping the remai
|
||||
(Results)
|
||||
|
||||
┌───────────────────────────────────┐
|
||||
│ Tests: 23 │
|
||||
│ Passing: 18 │
|
||||
│ Tests: 25 │
|
||||
│ Passing: 20 │
|
||||
│ Failing: 4 │
|
||||
│ Pending: 1 │
|
||||
│ Skipped: 0 │
|
||||
│ Screenshots: 26 │
|
||||
│ Screenshots: 28 │
|
||||
│ Video: true │
|
||||
│ Duration: X seconds │
|
||||
│ Spec Ran: screenshots_spec.js │
|
||||
@@ -115,6 +117,8 @@ Because this error occurred during a 'after each' hook we are skipping the remai
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/taking screenshots -- ensures unique paths when there's a non-named screenshot and a failure.png (1000x660)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/taking screenshots -- ensures unique paths when there's a non-named screenshot and a failure (failed).png (1280x720)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/aut-resize.png (1000x2000)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/element-padding.png (420x320)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/non-element-padding.png (600x200)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/app-clip.png (100x50)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/runner-clip.png (120x60)
|
||||
- /foo/bar/.projects/e2e/cypress/screenshots/screenshots_spec.js/fullPage-clip.png (140x70)
|
||||
@@ -139,9 +143,9 @@ Because this error occurred during a 'after each' hook we are skipping the remai
|
||||
|
||||
Spec Tests Passing Failing Pending Skipped
|
||||
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ✖ screenshots_spec.js XX:XX 23 18 4 1 - │
|
||||
│ ✖ screenshots_spec.js XX:XX 25 20 4 1 - │
|
||||
└────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||||
1 of 1 failed (100%) XX:XX 23 18 4 1 -
|
||||
1 of 1 failed (100%) XX:XX 25 20 4 1 -
|
||||
|
||||
|
||||
`
|
||||
|
||||
+31
@@ -264,6 +264,37 @@ describe('taking screenshots', () => {
|
||||
this.skip()
|
||||
})
|
||||
|
||||
it('adds padding to element screenshot when specified', () => {
|
||||
cy.visit('http://localhost:3322/element')
|
||||
cy.get('.element')
|
||||
.screenshot('element-padding', {
|
||||
padding: 10,
|
||||
})
|
||||
|
||||
cy.task('check:screenshot:size', {
|
||||
name: `${path.basename(__filename)}/element-padding.png`,
|
||||
width: 420,
|
||||
height: 320,
|
||||
devicePixelRatio,
|
||||
})
|
||||
})
|
||||
|
||||
it('does not add padding to non-element screenshot', () => {
|
||||
cy.viewport(600, 200)
|
||||
cy.visit('http://localhost:3322/color/yellow')
|
||||
cy.screenshot('non-element-padding', {
|
||||
capture: 'viewport',
|
||||
padding: 10,
|
||||
})
|
||||
|
||||
cy.task('check:screenshot:size', {
|
||||
name: `${path.basename(__filename)}/non-element-padding.png`,
|
||||
width: 600,
|
||||
height: 200,
|
||||
devicePixelRatio,
|
||||
})
|
||||
})
|
||||
|
||||
context('before hooks', () => {
|
||||
before(() => {
|
||||
// failure 2
|
||||
|
||||
Reference in New Issue
Block a user