带有反应和 google API 服务的赛普拉斯 - 如何存根自动完成
Cypress with react and google API services - how to stub autocomplete
我正在尝试测试一个反应 web 应用程序(在一个单独的项目中创建),它包含一个弹出窗口,其中有一个包含 google 城市自动完成的输入:
(因为语言原因我改了文字)
我在“搜索城市”中有一个文本输入,如果插入数据,google 搜索城市和 returns 结果(例如我搜索意大利罗马):
当我按下“保存数据”时,有一个功能会检查 google 结果,然后关闭弹出窗口:
在文件中:
export const useGoogleApiDesktop = () => {
let autocompleteService
if (window.google && window.google.maps) {
autocompleteService = new window.google.maps.places.AutocompleteService()
}
}
在另一个文件中(名为的文件):
const googleApi = useGoogleApiDesktop()
const onSubmitClick = useCallback(async () => {
[...]
const res: GoogleApiPlacesResponse = await googleApi.autocompleteService.getPlacePredictions({
input: addressComputed,
types: ['(cities)'],
componentRestrictions: { country: 'it' }
})
}, [])
当我在普通浏览器中使用它时,一切正常;
但是如果我尝试用 cypress 启动它来测试它,它 returns 我这个错误:
我试图避免这个错误,只是继续并关闭弹出窗口,因为在我的测试期间,我不需要在该行上写任何东西;我只需要在其他文本区域上写点东西并关闭弹出窗口。
因为我做不到,所以我试图打断那个电话,但我完全不熟悉 cy.stub()
并且不起作用:
function selectAddress(bookingConfig) {
// opens the popup
cy.get('.reservationsWhereAdd').click()
// trying to add the google library
const win = cy.state('window')
const document = win.document
const script = document.createElement('script')
script.src = `https://maps.googleapis.com/maps/api/js?key=[myApiKey]&libraries=places&language=it`
script.async = true
// this is commented since I don't think I need it
// window.initMap = function () {
// // JS API is loaded and available
// console.log('lanciato')
// }
// Append the ‘script’ element to ‘head’
document.head.appendChild(script)
// type something in some fields
cy.get('#street').type(bookingConfig.street)
cy.get('#streetNumber').type(bookingConfig.streetNum)
cy.get('#nameOnTheDoorbell').type(bookingConfig.nameOnTheDoorbell)
cy.get('#addressAlias').type(bookingConfig.addressAlias)
// this correctly finds and prints the object
console.log('--->', win.google.maps.places)
cy.stub(googleApi.autocompleteService, 'getPlacePredictions')
// this closes the popup
cy.get('.flex-1 > .btn').click()
}
这个 cy.stub
但是不起作用,我不明白为什么:它说
googleApi is not defined
知道如何解决这个问题吗?谢谢!
更新:
错误后,使用cypress window,我手动关闭弹出窗口,重新打开,填写字段,然后点击保存数据。它起作用了,所以我在打开弹出窗口后添加了一个 cy.wait(1000)
,它在 95% 的时间里都起作用(9 次对 10 次)。关于如何“等待加载 google api,然后填写字段”的任何想法?
正如更新块所说,我发现问题在于加载 google API 的时间非常长,因为它不是本地的,需要时间来检索。
所以一开始我只是在执行我的代码之前放了一个cy.wait(2000)
;但这不是答案:如果我 运行 代码在慢速网络上会怎样?或者如果我的应用程序需要更多时间来加载?
所以,我创建了一个命令,首先等待 google API 加载;如果在 5 次尝试后加载失败,则测试失败。
然后,在那之后,我的代码正在执行。这样我的测试就不会轻易失败。
代码如下:
在cypress/support/command.js
Cypress.Commands.add('waitForGoogleApi', () => {
let mapWaitCount = 0
const mapWaitMax = 5
cyMapLoad()
function cyMapLoad() {
mapWaitCount++
cy.window().then(win => {
if (typeof win.google != 'undefined') {
console.log(`Done at attempt #${mapWaitCount}:`, win)
return true
} else if (mapWaitCount <= mapWaitMax) {
console.log('Waiting attempt #' + mapWaitCount) // just log
cy.wait(2000)
cyMapLoad()
} else if (mapWaitCount > mapWaitMax) {
console.log('Failed to load google api')
return false
}
})
}
})
在您要使用的文件中:
cy.waitForGoogleApi().then(() => {
// here comes the code to execute after loading the google Apis
})
我正在尝试测试一个反应 web 应用程序(在一个单独的项目中创建),它包含一个弹出窗口,其中有一个包含 google 城市自动完成的输入:
(因为语言原因我改了文字)
我在“搜索城市”中有一个文本输入,如果插入数据,google 搜索城市和 returns 结果(例如我搜索意大利罗马):
当我按下“保存数据”时,有一个功能会检查 google 结果,然后关闭弹出窗口:
在文件中:
export const useGoogleApiDesktop = () => {
let autocompleteService
if (window.google && window.google.maps) {
autocompleteService = new window.google.maps.places.AutocompleteService()
}
}
在另一个文件中(名为的文件):
const googleApi = useGoogleApiDesktop()
const onSubmitClick = useCallback(async () => {
[...]
const res: GoogleApiPlacesResponse = await googleApi.autocompleteService.getPlacePredictions({
input: addressComputed,
types: ['(cities)'],
componentRestrictions: { country: 'it' }
})
}, [])
当我在普通浏览器中使用它时,一切正常; 但是如果我尝试用 cypress 启动它来测试它,它 returns 我这个错误:
我试图避免这个错误,只是继续并关闭弹出窗口,因为在我的测试期间,我不需要在该行上写任何东西;我只需要在其他文本区域上写点东西并关闭弹出窗口。
因为我做不到,所以我试图打断那个电话,但我完全不熟悉 cy.stub()
并且不起作用:
function selectAddress(bookingConfig) {
// opens the popup
cy.get('.reservationsWhereAdd').click()
// trying to add the google library
const win = cy.state('window')
const document = win.document
const script = document.createElement('script')
script.src = `https://maps.googleapis.com/maps/api/js?key=[myApiKey]&libraries=places&language=it`
script.async = true
// this is commented since I don't think I need it
// window.initMap = function () {
// // JS API is loaded and available
// console.log('lanciato')
// }
// Append the ‘script’ element to ‘head’
document.head.appendChild(script)
// type something in some fields
cy.get('#street').type(bookingConfig.street)
cy.get('#streetNumber').type(bookingConfig.streetNum)
cy.get('#nameOnTheDoorbell').type(bookingConfig.nameOnTheDoorbell)
cy.get('#addressAlias').type(bookingConfig.addressAlias)
// this correctly finds and prints the object
console.log('--->', win.google.maps.places)
cy.stub(googleApi.autocompleteService, 'getPlacePredictions')
// this closes the popup
cy.get('.flex-1 > .btn').click()
}
这个 cy.stub
但是不起作用,我不明白为什么:它说
googleApi is not defined
知道如何解决这个问题吗?谢谢!
更新:
错误后,使用cypress window,我手动关闭弹出窗口,重新打开,填写字段,然后点击保存数据。它起作用了,所以我在打开弹出窗口后添加了一个 cy.wait(1000)
,它在 95% 的时间里都起作用(9 次对 10 次)。关于如何“等待加载 google api,然后填写字段”的任何想法?
正如更新块所说,我发现问题在于加载 google API 的时间非常长,因为它不是本地的,需要时间来检索。
所以一开始我只是在执行我的代码之前放了一个cy.wait(2000)
;但这不是答案:如果我 运行 代码在慢速网络上会怎样?或者如果我的应用程序需要更多时间来加载?
所以,我创建了一个命令,首先等待 google API 加载;如果在 5 次尝试后加载失败,则测试失败。 然后,在那之后,我的代码正在执行。这样我的测试就不会轻易失败。
代码如下:
在cypress/support/command.js
Cypress.Commands.add('waitForGoogleApi', () => {
let mapWaitCount = 0
const mapWaitMax = 5
cyMapLoad()
function cyMapLoad() {
mapWaitCount++
cy.window().then(win => {
if (typeof win.google != 'undefined') {
console.log(`Done at attempt #${mapWaitCount}:`, win)
return true
} else if (mapWaitCount <= mapWaitMax) {
console.log('Waiting attempt #' + mapWaitCount) // just log
cy.wait(2000)
cyMapLoad()
} else if (mapWaitCount > mapWaitMax) {
console.log('Failed to load google api')
return false
}
})
}
})
在您要使用的文件中:
cy.waitForGoogleApi().then(() => {
// here comes the code to execute after loading the google Apis
})