1
0
mirror of https://github.com/MontFerret/ferret.git synced 2025-04-23 12:18:46 +02:00
2018-09-23 04:33:20 -04:00

97 lines
1.7 KiB
Go

package browser
import (
"context"
"encoding/json"
"fmt"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/mafredri/cdp"
"github.com/mafredri/cdp/protocol/runtime"
"time"
)
type WaitTask struct {
client *cdp.Client
predicate string
timeout time.Duration
}
func NewWaitTask(
client *cdp.Client,
predicate string,
timeout time.Duration,
) *WaitTask {
return &WaitTask{
client,
fmt.Sprintf("((function () {%s})())", predicate),
timeout,
}
}
func (task *WaitTask) Run() (core.Value, error) {
var result core.Value = values.None
var err error
var done bool
timer := time.NewTimer(task.timeout)
for !done {
select {
case <-timer.C:
err = core.ErrTimeout
done = true
default:
out, e := task.exec()
if e != nil {
done = true
timer.Stop()
err = e
break
}
if out != values.None {
timer.Stop()
result = out
done = true
break
}
}
}
return result, err
}
func (task *WaitTask) exec() (core.Value, error) {
args := runtime.NewEvaluateArgs(task.predicate).SetReturnByValue(true)
out, err := task.client.Runtime.Evaluate(context.Background(), args)
if err != nil {
return values.None, err
}
if out.ExceptionDetails != nil {
ex := out.ExceptionDetails
return values.None, core.Error(
core.ErrUnexpected,
fmt.Sprintf("%s %s", ex.Text, *ex.Exception.Description),
)
}
if out.Result.Type != "undefined" {
var o interface{}
err := json.Unmarshal(out.Result.Value, &o)
if err != nil {
return values.None, core.Error(core.ErrUnexpected, err.Error())
}
return values.Parse(o), nil
}
return values.None, nil
}