refactor: close popup handler

This commit is contained in:
lilong.129
2023-09-22 14:15:55 +08:00
parent fa34cd9a8f
commit 27297da8d3
8 changed files with 90 additions and 93 deletions
+79 -55
View File
@@ -88,12 +88,54 @@ type ClosePopupsResult struct {
}
type PopupInfo struct {
*ClosePopupsResult
CloseStatus string `json:"close_status"` // found/success/fail
RetryCount int `json:"retry_count"`
CloseBox Box `json:"close_box"` // CV 识别的弹窗关闭按钮(弹窗存在 && 关闭按钮存在)
ClosePoints []PointF `json:"close_points,omitempty"` // CV 识别的所有关闭按钮(仅关闭按钮,可能存在多个)
}
func (p *PopupInfo) getClosePoint() (*PointF, error) {
closeResult := p.ClosePopupsResult
if closeResult == nil {
return nil, nil
}
// 弹框不存在 & 关闭按钮不存在
if closeResult.PopupArea.IsEmpty() && closeResult.CloseArea.IsEmpty() {
if p.ClosePoints == nil {
// 关闭图标不存在 => 100% 确定不存在弹窗
return nil, nil
}
// TODO: 结合连续两次关闭图标判断
// 若连续两次都存在关闭图标,且位置相同 => 存在弹窗 => 点击关闭
return nil, nil
}
// 弹窗存在 & 关闭按钮不存在
if !closeResult.PopupArea.IsEmpty() && closeResult.CloseArea.IsEmpty() {
if p.ClosePoints == nil {
// 关闭图标不存在 => 无法处理,抛异常
log.Error().Interface("popup", p).Msg("popup close area not found")
return nil, errors.New("popup close area not found")
}
// 使用关闭图标作为关闭按钮
return &p.ClosePoints[0], nil
}
closePoint := closeResult.CloseArea.Center()
// 弹窗不存在 & 关闭按钮存在 => 可能是文字弹窗 => 基于关闭按钮关闭弹窗
if closeResult.PopupArea.IsEmpty() && !closeResult.CloseArea.IsEmpty() {
return &closePoint, nil
}
// 弹窗存在 & 关闭按钮存在 => 检测到弹窗存在 => 基于关闭按钮关闭弹窗
return &closePoint, nil
}
func (p *PopupInfo) isIdentical(lastPopup *PopupInfo) bool {
if lastPopup == nil {
return false
@@ -111,65 +153,46 @@ func (p *PopupInfo) isIdentical(lastPopup *PopupInfo) bool {
return true
}
func (dExt *DriverExt) ClosePopupsHandler(options ...ActionOption) error {
actionOptions := NewActionOptions(options...)
log.Info().Interface("actionOptions", actionOptions).Msg("try to find and close popups")
maxRetryTimes := actionOptions.MaxRetryTimes
interval := actionOptions.Interval
func (dExt *DriverExt) ClosePopupsHandler() (err error) {
log.Info().Msg("try to find and close popups")
var lastPopup *PopupInfo
for retryCount := 0; retryCount < maxRetryTimes; retryCount++ {
screenResult, err := dExt.GetScreenResult(
WithScreenShotUpload(true),
WithScreenShotClosePopups(true),
WithScreenShotUITypes("close"), // get all close buttons
)
if err != nil {
log.Error().Err(err).Msg("get screen result failed for popup handler")
continue
}
popup := screenResult.Popup
if popup == nil || popup.CloseBox.IsEmpty() {
log.Debug().Interface("popup", popup).Msg("no popup found")
break
}
popup.CloseStatus = CloseStatusFound
popup.RetryCount = retryCount
// check if the current popup equals to the last popup
if popup.isIdentical(lastPopup) {
return errors.Wrap(code.MobileUIPopupError, "handle popup failed")
}
if err = dExt.tapPopupHandler(popup); err != nil {
return err
}
// sleep for another popup (if existed) to pop
time.Sleep(time.Duration(1000*interval) * time.Millisecond)
lastPopup = popup
screenResult, err := dExt.GetScreenResult(
WithScreenShotUpload(true),
WithScreenShotClosePopups(true), // get popup area and close area
WithScreenShotUITypes("close"), // get all close buttons
)
if err != nil {
log.Error().Err(err).Msg("get screen result failed for popup handler")
return err
}
return nil
}
func (dExt *DriverExt) tapPopupHandler(popup *PopupInfo) error {
if popup == nil || popup.CloseBox.IsEmpty() {
log.Debug().Interface("popup", popup).Msg("no popup found")
popup := screenResult.Popup
defer func() {
if err != nil {
dExt.lastPopup = popup
} else {
dExt.lastPopup = nil
}
}()
// TODO: check if the current popup equals to the last popup
// if popup.isIdentical(dExt.lastPopup) {
// return errors.Wrap(code.MobileUIPopupError, "handle popup failed")
// }
closePoint, err := popup.getClosePoint()
if err != nil {
return err
}
if closePoint == nil {
// close point not found
log.Debug().Interface("", popup.ClosePoints).Msg("close point not found")
return nil
}
popup.CloseStatus = CloseStatusFound
popupClose := popup.CloseBox
if popupClose.IsEmpty() {
log.Error().
Interface("popup", popup).
Msg("popup close area not found")
return errors.Wrap(code.MobileUIPopupError,
"popup close area not found")
}
closePoint := popupClose.Center()
log.Info().
Interface("popup", popup).
Interface("closePoint", closePoint).
@@ -179,6 +202,7 @@ func (dExt *DriverExt) tapPopupHandler(popup *PopupInfo) error {
return errors.Wrap(code.MobileUIPopupError, err.Error())
}
// tap popup success
return nil
// wait 1s and check if popup still exists
time.Sleep(1 * time.Second)
return dExt.ClosePopupsHandler()
}