/
sync.spec.js
128 lines (118 loc) 路 3.98 KB
/
sync.spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* @copyright Copyright (c) 2023 Max <max@nextcloud.com>
*
* @author Max <max@nextcloud.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { randUser } from '../utils/index.js'
const user = randUser()
describe('Sync', () => {
before(() => {
cy.createUser(user)
})
beforeEach(() => {
cy.login(user)
cy.uploadTestFile('test.md')
cy.visit('/apps/files')
cy.intercept({ method: 'POST', url: '**/apps/text/session/sync' }, (req) => {
if (req.body.autosaveContent) {
req.alias = 'save'
}
}).as('sync')
cy.openTestFile()
cy.getContent().find('h2').should('contain', 'Hello world')
cy.getContent().type('* Saving the doc saves the doc state{enter}')
})
it('saves the actual file and document state', () => {
cy.getContent().type('{ctrl+s}')
cy.wait('@save').its('request.body')
.should('have.property', 'documentState')
.should('not.be.empty')
cy.testName()
.then(name => cy.downloadFile(`/${name}.md`))
.its('data')
.should('include', 'saves the doc state')
cy.closeFile()
})
it('saves on close', () => {
cy.closeFile()
cy.wait('@save')
cy.testName()
.then(name => cy.downloadFile(`/${name}.md`))
.its('data')
.should('include', 'saves the doc state')
})
it('recovers from a lost connection', () => {
let count = 0
cy.intercept({ method: 'PUT', url: '**/apps/text/session/create' })
.as('createSession')
cy.intercept({ method: 'POST', url: '**/apps/text/session/*' }, (req) => {
if (count < 4) {
req.destroy()
req.alias = 'dead'
} else {
req.alias = 'alive'
}
}).as('sessionRequests')
cy.wait('@dead', { timeout: 30000 })
cy.get('#editor-container .document-status', { timeout: 10000 })
.should('contain', 'File could not be loaded')
.then(() => {
count = 4
})
cy.wait('@alive', { timeout: 30000 })
cy.intercept({ method: 'POST', url: '**/apps/text/session/sync' })
.as('syncAfterRecovery')
cy.wait('@syncAfterRecovery', { timeout: 30000 })
cy.get('#editor-container .document-status', { timeout: 30000 })
.should('not.contain', 'File could not be loaded')
// FIXME: There seems to be a bug where typed words maybe lost if not waiting for the new session
cy.wait('@createSession')
cy.wait('@syncAfterRecovery')
cy.getContent().type('* more content added after the lost connection{enter}')
cy.wait('@syncAfterRecovery')
cy.closeFile()
cy.testName()
.then(name => cy.downloadFile(`/${name}.md`))
.its('data')
.should('include', 'after the lost connection')
})
it('passes the doc content from one session to the next', () => {
cy.closeFile()
cy.intercept({ method: 'PUT', url: '**/apps/text/session/create' })
.as('create')
cy.openTestFile()
cy.wait('@create', { timeout: 10000 })
.its('response.body')
.should('have.property', 'documentState')
.should('not.be.empty')
cy.getContent().find('h2').should('contain', 'Hello world')
cy.getContent().find('li').should('contain', 'Saving the doc saves the doc state')
cy.getContent().type('recovered')
cy.closeFile()
})
// regression test #3834
it('close triggers one close request', () => {
cy.closeFile()
// Wait to make sure there is enough time for all close requests to run
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(100)
// reuse @close intercepted in closeFile()
cy.get('@close.all').should('have.length', 1)
})
})