Cypress在每个测试之间使用时钟,无需再次访问。

huangapple go评论65阅读模式
英文:

Cypress use clock between each test without visit again

问题

I understand that you want a translation of the code-related content. Here's the translation of the code part:

// test.cy.ts

before(() => {
  cy.clock(0, ['setInterval']);
  cy.visit('my component url');
});

describe('test clock', () => {
  it('test1', () => {
    cy.tick(20000); // Work
    // Successfully call the API
  });

  it('test2', () => {
    cy.tick(20000); // Error, you need to call cy.clock before calling cy.tick
  });
});

Please let me know if you need any further assistance with this code or if you have any additional questions.

英文:

I have a component which will call api every 20 seconds(setInterval)

and I wanna test if the api return different result, what will my component show.

I try to speed up the setInterval with cy.clock and cy.tick , but it only works in the first test.

there is my code:

// test.cy.ts

before(()=>{
  cy.clock(0,['setInterval'])
  cy.visit('my component url')
})
describe('test clock',()=>{
  it('test1',()=>{
    cy.tick(20000) // work
    // call API successfully
  })
  it('test2',()=>{
    cy.tick(20000) // error, you need to call cy.clock before calling cy.tick
  })
})

I try to add cy.clock in 'test2' before I call cy.tick(20000) , and there has no error but still not working.(I dunno why but API doesn't be called)

I try the answer here:
https://stackoverflow.com/questions/70702941/cy-clock-and-cy-tick-not-working-with-split-code

but get error: Cannot read properties of null (reading 'details')

I wondering it's cuz Cypress will automatically call restore between tests.

clock need to be called before setInterval, that's might be the reason I add a new clock and doesn't work.

is there any way to use the same clock function without visit the page again?


edit:

I've tried the two answer below but still not working

the clock stop at 1000 and doesn't change to 2000

I'm using Vue3 and Cypress v12.11.0 with chrome v113

there is my testing code:
it looks very noraml when I visit the page without cypress

// test.vue
<template>
  <div data-test="number">{{number}}</div>
</template>

<script lang="ts" setup>
import {onMounted,ref,} from 'vue'

var number = ref(0)
onMounted(()=>{
  setInterval(() => {
    number.value += 1
  }, 1000)
})
</script>
// test1.cy.ts
describe('test clock', () => {
  beforeEach(() => {
    cy.clock(0, ['setInterval']);
    cy.visit('http://localhost:3000/#/index/dashboardview2');
  });

  it('test1', () => {
    cy.get('[data-test="number"]').should('have.text', '0')
    cy.tick(1000); // Work
    cy.get('[data-test="number"]').should('have.text', '1')
  });

  it('test2', () => {
    cy.get('[data-test="number"]').should('have.text', '1')
    cy.tick(1000); // doesn't work
    cy.get('[data-test="number"]').should('have.text', '2')
  });
});
// test2.cy.ts
describe('clock and interval test - with test isolation off', 
{testIsolation: false}, () => {
before(() => {
cy.visit('http://localhost:3000/#/index/dashboardview2')  // timer continues between tests
})
beforeEach(() => {
cy.clock()
})
it('ticks 1 second', () => {
cy.get('[data-test="number"]').should('have.text', '0')
cy.tick(1000)
cy.get('[data-test="number"]').should('have.text', '1')
})
it('ticks 2 seconds', () => {
cy.get('[data-test="number"]').should('have.text', '1')
cy.tick(1000)
cy.get('[data-test="number"]').should('have.text', '2')
})
})

there is the error:

Cypress在每个测试之间使用时钟,无需再次访问。

答案1

得分: 6

If you want to apply cy.clock() for both tests, change before() to beforeEach(). This runs the code inside before each test.

Here is a full test showing the options.

Isolated tests:

describe('clock and interval test - with test isolation on', 
  {testIsolation: true}, () => {

  beforeEach(() => {
    cy.clock()
    cy.visit('/')  // timer reset each visit
  })
  it('ticks 1 second', () => {
    cy.get('div').should('have.text', '0')
    cy.tick(1000)
    cy.get('div').should('have.text', '1')
  })
  it('ticks 1 second', () => {
    cy.get('div').should('have.text', '0')
    cy.tick(1000)
    cy.get('div').should('have.text', '1')
  })
})

Non-isolated tests:

describe('clock and interval test - with test isolation off', 
  {testIsolation: false}, () => {

  before(() => {
    cy.visit('/')  // timer continues between tests
  })
  beforeEach(() => {
    cy.clock()
  })
  it('ticks 1 second', () => {
    cy.get('div').should('have.text', '0')
    cy.tick(1000)
    cy.get('div').should('have.text', '1')
  })
  it('ticks 2 seconds', () => {
    cy.get('div').should('have.text', '1')
    cy.tick(1000)
    cy.get('div').should('have.text', '2')
  })
})

This is the test page (simple counter):

<div>0</div>
<script>
  setInterval(() => {
    const div = document.querySelector('div')
    div.innerText = +div.innerText +1
  }, 1000)
</script>
英文:

If you want to apply cy.clock() for both tests, change before() to beforeEach(). This runs the code inside before each test.

Here is a full test showing the options.

Isolated tests:

describe(&#39;clock and interval test - with test isolation on&#39;, 
  {testIsolation: true}, () =&gt; {

  beforeEach(() =&gt; {
    cy.clock()
    cy.visit(&#39;/&#39;)  // timer reset each visit
  })
  it(&#39;ticks 1 second&#39;, () =&gt; {
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;0&#39;)
    cy.tick(1000)
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
  })
  it(&#39;ticks 1 seconds&#39;, () =&gt; {
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;0&#39;)
    cy.tick(1000)
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
  })
})

Non-isolated tests:

describe(&#39;clock and interval test - with test isolation off&#39;, 
  {testIsolation: false}, () =&gt; {

  before(() =&gt; {
    cy.visit(&#39;/&#39;)  // timer continues between tests
  })
  beforeEach(() =&gt; {
    cy.clock()
  })
  it(&#39;ticks 1 second&#39;, () =&gt; {
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;0&#39;)
    cy.tick(1000)
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
  })
  it(&#39;ticks 2 seconds&#39;, () =&gt; {
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
    cy.tick(1000)
    cy.get(&#39;div&#39;).should(&#39;have.text&#39;, &#39;2&#39;)
  })
})

This is the test page (simple counter):

&lt;div&gt;0&lt;/div&gt;
&lt;script&gt;
  setInterval(() =&gt; {
    const div = document.querySelector(&#39;div&#39;)
    div.innerText = +div.innerText +1
  }, 1000)
&lt;/script&gt;

答案2

得分: -1

我创建了一个新项目,只包含Vue、Vite和Cypress。这段代码运行良好。

在检查了我旧项目的所有设置后,没有奇怪的设置。
我还发现,当第一次运行npx cypress open时,它也能正常工作。

最后,我通过在检查页面加载后使用时钟来解决了这个问题。

describe('clock and interval test - with test isolation off', 
  {testIsolation: false}, () => {

  before(()=>{
    cy.visit('http://localhost:3000/#/index/dashboardview2').then(()=>{
      expect(cy.get('[data-test="number"]').should('be.visible'))
    })
  })
  beforeEach(()=>{
    cy.clock()
  })
  it('ticks 1 second', () => {
    cy.get('[data-test="number"]').should('have.text', '0')
    cy.tick(1000)
    cy.get('[data-test="number"]').should('have.text', '1')
  })
  it('ticks 2 seconds', () => {
    cy.get('[data-test="number"]').should('have.text', '1')
    cy.tick(1000) // finally works
    cy.get('[data-test="number"]').should('have.text', '2')
  })
})

我猜这是因为我的项目在尝试访问页面时会首先检查某些内容(例如令牌等),这需要一些时间。

所以我需要在使用时钟之前检查数字是否可见。

谢谢大家!

英文:

I created a new project which is only have Vue, Vite and Cypress.
this code works well.

after checking all setting in my old project, there is no weird setting.<br>
also I find that it works well when the first time runing npx cypress open.

finally I solved it by use clock after checking page is loaded.

describe(&#39;clock and interval test - with test isolation off&#39;, 
{testIsolation: false}, () =&gt; {
before(()=&gt;{
cy.visit(&#39;http://localhost:3000/#/index/dashboardview2&#39;).then(()=&gt;{
expect(cy.get(&#39;[data-test=&quot;number&quot;]&#39;).should(&#39;be.visible&#39;))
})
})
beforeEach(()=&gt;{
cy.clock()
})
it(&#39;ticks 1 second&#39;, () =&gt; {
cy.get(&#39;[data-test=&quot;number&quot;]&#39;).should(&#39;have.text&#39;, &#39;0&#39;)
cy.tick(1000)
cy.get(&#39;[data-test=&quot;number&quot;]&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
})
it(&#39;ticks 2 seconds&#39;, () =&gt; {
cy.get(&#39;[data-test=&quot;number&quot;]&#39;).should(&#39;have.text&#39;, &#39;1&#39;)
cy.tick(1000) // finally works
cy.get(&#39;[data-test=&quot;number&quot;]&#39;).should(&#39;have.text&#39;, &#39;2&#39;)
})
})

I guess that's cuz my project will check something first when you try to visit page(like token or sth), it takes time to do that.

so I need to check the number is visible before I use clock.

thx for everyone!

huangapple
  • 本文由 发表于 2023年5月18日 13:49:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76278064.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定