mirror of
https://github.com/MontFerret/ferret.git
synced 2024-12-12 11:15:14 +02:00
Added possibility to set custom viewport size (#334)
* Added possibility to set custom viewport size * Fixed linting issue * Renamed ScreenSize to Viewport * Updated e2e test
This commit is contained in:
parent
8483174da1
commit
63201148ac
@ -3,6 +3,7 @@ import IndexPage from './pages/index.js';
|
||||
import FormsPage from './pages/forms/index.js';
|
||||
import EventsPage from './pages/events/index.js';
|
||||
import IframePage from './pages/iframes/index.js';
|
||||
import MediaPage from './pages/media/index.js';
|
||||
|
||||
const e = React.createElement;
|
||||
const Router = ReactRouter.Router;
|
||||
@ -51,6 +52,10 @@ export default React.memo(function AppComponent(params = {}) {
|
||||
path: '/iframe',
|
||||
component: IframePage
|
||||
}),
|
||||
e(Route, {
|
||||
path: '/media',
|
||||
component: MediaPage
|
||||
}),
|
||||
]),
|
||||
redirectTo
|
||||
])
|
||||
|
26
e2e/pages/dynamic/components/pages/media/index.js
Normal file
26
e2e/pages/dynamic/components/pages/media/index.js
Normal file
@ -0,0 +1,26 @@
|
||||
const e = React.createElement;
|
||||
|
||||
export default class MediaPage extends React.Component {
|
||||
render() {
|
||||
return e("div", { id: "media" }, [
|
||||
e("div", { className: "row" }, [
|
||||
e("div", {className: "col-6"}, [
|
||||
e("h3", null, [
|
||||
"Height"
|
||||
]),
|
||||
e("span", { id: "screen-height"}, [
|
||||
window.innerHeight
|
||||
]),
|
||||
]),
|
||||
e("div", {className: "col-6"}, [
|
||||
e("h3", null, [
|
||||
"Width"
|
||||
]),
|
||||
e("span", { id: "screen-width"}, [
|
||||
window.innerWidth
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
}
|
||||
}
|
16
e2e/tests/dynamic/doc/viewport/size.fql
Normal file
16
e2e/tests/dynamic/doc/viewport/size.fql
Normal file
@ -0,0 +1,16 @@
|
||||
LET url = @dynamic + "?redirect=/media"
|
||||
LET expectedW = 1920
|
||||
LET expectedH = 1080
|
||||
|
||||
LET doc = DOCUMENT(url, {
|
||||
driver: 'cdp',
|
||||
viewport: {
|
||||
width: expectedW,
|
||||
height: expectedH
|
||||
}
|
||||
})
|
||||
|
||||
LET actualW = TO_INT(INNER_TEXT(doc, '#screen-width'))
|
||||
LET actualH = TO_INT(INNER_TEXT(doc, '#screen-height'))
|
||||
|
||||
RETURN EXPECT(expectedW, actualW) + EXPECT(expectedH, actualH)
|
@ -20,6 +20,11 @@ const DriverName = "cdp"
|
||||
const BlankPageURL = "about:blank"
|
||||
const DefaultTimeout = 5000 * time.Millisecond
|
||||
|
||||
var defaultViewport = &drivers.Viewport{
|
||||
Width: 1600,
|
||||
Height: 900,
|
||||
}
|
||||
|
||||
type Driver struct {
|
||||
mu sync.Mutex
|
||||
dev *devtool.DevTools
|
||||
@ -42,7 +47,7 @@ func (drv *Driver) Name() string {
|
||||
return drv.options.Name
|
||||
}
|
||||
|
||||
func (drv *Driver) Open(ctx context.Context, params drivers.OpenPageParams) (drivers.HTMLPage, error) {
|
||||
func (drv *Driver) Open(ctx context.Context, params drivers.Params) (drivers.HTMLPage, error) {
|
||||
logger := logging.FromContext(ctx)
|
||||
|
||||
err := drv.init(ctx)
|
||||
@ -98,6 +103,10 @@ func (drv *Driver) Open(ctx context.Context, params drivers.OpenPageParams) (dri
|
||||
params.UserAgent = drv.options.UserAgent
|
||||
}
|
||||
|
||||
if params.Viewport == nil {
|
||||
params.Viewport = defaultViewport
|
||||
}
|
||||
|
||||
return LoadHTMLPage(ctx, conn, params)
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ func handleLoadError(logger *zerolog.Logger, client *cdp.Client) {
|
||||
func LoadHTMLPage(
|
||||
ctx context.Context,
|
||||
conn *rpcc.Conn,
|
||||
params drivers.OpenPageParams,
|
||||
params drivers.Params,
|
||||
) (*HTMLPage, error) {
|
||||
logger := logging.FromContext(ctx)
|
||||
|
||||
@ -56,11 +56,11 @@ func LoadHTMLPage(
|
||||
|
||||
client := cdp.NewClient(conn)
|
||||
|
||||
err := runBatch(
|
||||
func() error {
|
||||
return client.Page.Enable(ctx)
|
||||
},
|
||||
if err := client.Page.Enable(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := runBatch(
|
||||
func() error {
|
||||
return client.Page.SetLifecycleEventsEnabled(
|
||||
ctx,
|
||||
@ -99,18 +99,50 @@ func LoadHTMLPage(
|
||||
func() error {
|
||||
return client.Network.Enable(ctx, network.NewEnableArgs())
|
||||
},
|
||||
|
||||
func() error {
|
||||
return client.Page.SetBypassCSP(ctx, page.NewSetBypassCSPArgs(true))
|
||||
},
|
||||
|
||||
func() error {
|
||||
if params.Viewport == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
orientation := emulation.ScreenOrientation{}
|
||||
|
||||
if !params.Viewport.Landscape {
|
||||
orientation.Type = "portraitPrimary"
|
||||
orientation.Angle = 0
|
||||
} else {
|
||||
orientation.Type = "landscapePrimary"
|
||||
orientation.Angle = 90
|
||||
}
|
||||
|
||||
scaleFactor := params.Viewport.ScaleFactor
|
||||
|
||||
if scaleFactor <= 0 {
|
||||
scaleFactor = 1
|
||||
}
|
||||
|
||||
deviceArgs := emulation.NewSetDeviceMetricsOverrideArgs(
|
||||
params.Viewport.Width,
|
||||
params.Viewport.Height,
|
||||
scaleFactor,
|
||||
params.Viewport.Mobile,
|
||||
).SetScreenOrientation(orientation)
|
||||
|
||||
return client.Emulation.SetDeviceMetricsOverride(
|
||||
ctx,
|
||||
deviceArgs,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = client.Page.SetBypassCSP(ctx, page.NewSetBypassCSPArgs(true))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if params.Cookies != nil {
|
||||
cookies := make([]network.CookieParam, 0, len(params.Cookies))
|
||||
|
||||
|
@ -18,18 +18,10 @@ type (
|
||||
drivers map[string]Driver
|
||||
}
|
||||
|
||||
OpenPageParams struct {
|
||||
URL string
|
||||
UserAgent string
|
||||
KeepCookies bool
|
||||
Cookies []HTTPCookie
|
||||
Header HTTPHeader
|
||||
}
|
||||
|
||||
Driver interface {
|
||||
io.Closer
|
||||
Name() string
|
||||
Open(ctx context.Context, params OpenPageParams) (HTMLPage, error)
|
||||
Open(ctx context.Context, params Params) (HTMLPage, error)
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -62,7 +62,7 @@ func (drv *Driver) Name() string {
|
||||
return DriverName
|
||||
}
|
||||
|
||||
func (drv *Driver) Open(ctx context.Context, params drivers.OpenPageParams) (drivers.HTMLPage, error) {
|
||||
func (drv *Driver) Open(ctx context.Context, params drivers.Params) (drivers.HTMLPage, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, params.URL, nil)
|
||||
|
||||
if err != nil {
|
||||
|
20
pkg/drivers/params.go
Normal file
20
pkg/drivers/params.go
Normal file
@ -0,0 +1,20 @@
|
||||
package drivers
|
||||
|
||||
type (
|
||||
Viewport struct {
|
||||
Height int
|
||||
Width int
|
||||
ScaleFactor float64
|
||||
Mobile bool
|
||||
Landscape bool
|
||||
}
|
||||
|
||||
Params struct {
|
||||
URL string
|
||||
UserAgent string
|
||||
KeepCookies bool
|
||||
Cookies []HTTPCookie
|
||||
Header HTTPHeader
|
||||
Viewport *Viewport
|
||||
}
|
||||
)
|
@ -231,10 +231,10 @@ func Unmarshal(value json.RawMessage) (core.Value, error) {
|
||||
return Parse(o), nil
|
||||
}
|
||||
|
||||
func ToBoolean(input core.Value) core.Value {
|
||||
func ToBoolean(input core.Value) Boolean {
|
||||
switch input.Type() {
|
||||
case types.Boolean:
|
||||
return input
|
||||
return input.(Boolean)
|
||||
case types.String:
|
||||
return NewBoolean(input.(String) != "")
|
||||
case types.Int:
|
||||
|
@ -13,20 +13,23 @@ import (
|
||||
)
|
||||
|
||||
type PageLoadParams struct {
|
||||
drivers.OpenPageParams
|
||||
drivers.Params
|
||||
Driver string
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// Open opens an HTML page by a given url.
|
||||
// By default, loads a document by http call - resulted document does not support any interactions.
|
||||
// If passed "true" as a second argument, headless browser is used for loading the document which support interactions.
|
||||
// @param url (String) - Target url string. If passed "about:blank" for dynamic document - it will open an empty page.
|
||||
// @param isDynamicOrParams (Boolean|PageLoadParams) - Either a boolean value that indicates whether to use dynamic page
|
||||
// or an object with the following properties :
|
||||
// dynamic (Boolean) - Optional, indicates whether to use dynamic page.
|
||||
// timeout (Int) - Optional, Open load timeout.
|
||||
// @returns (HTMLDocument) - Returns loaded HTML document.
|
||||
// By default, loads a page by http call - resulted page does not support any interactions.
|
||||
// @param params (Object) - Optional, An object containing the following properties :
|
||||
// driver (String) - Optional, driver name.
|
||||
// timeout (Int) - Optional, timeout.
|
||||
// userAgent (String) - Optional, user agent.
|
||||
// keepCookies (Boolean) - Optional, boolean value indicating whether to use cookies from previous sessions.
|
||||
// i.e. not to open a page in the Incognito mode.
|
||||
// cookies (HTTPCookie) - Optional, set of HTTP cookies.
|
||||
// header (HTTPHeader) - Optional, HTTP headers.
|
||||
// viewport (Viewport) - Optional, viewport params.
|
||||
// @returns (HTMLPage) - Returns loaded HTML page.
|
||||
func Open(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||
err := core.ValidateArgs(args, 1, 2)
|
||||
|
||||
@ -65,12 +68,12 @@ func Open(ctx context.Context, args ...core.Value) (core.Value, error) {
|
||||
return values.None, err
|
||||
}
|
||||
|
||||
return drv.Open(ctx, params.OpenPageParams)
|
||||
return drv.Open(ctx, params.Params)
|
||||
}
|
||||
|
||||
func newDefaultDocLoadParams(url values.String) PageLoadParams {
|
||||
return PageLoadParams{
|
||||
OpenPageParams: drivers.OpenPageParams{
|
||||
Params: drivers.Params{
|
||||
URL: url.String(),
|
||||
},
|
||||
Timeout: time.Second * 30,
|
||||
@ -155,9 +158,19 @@ func newPageLoadParams(url values.String, arg core.Value) (PageLoadParams, error
|
||||
res.Header = header
|
||||
}
|
||||
|
||||
viewport, exists := obj.Get(values.NewString("viewport"))
|
||||
|
||||
if exists {
|
||||
viewport, err := parseViewport(viewport)
|
||||
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.Viewport = viewport
|
||||
}
|
||||
case types.String:
|
||||
res.Driver = arg.(values.String).String()
|
||||
|
||||
case types.Boolean:
|
||||
b := arg.(values.Boolean)
|
||||
|
||||
@ -165,7 +178,6 @@ func newPageLoadParams(url values.String, arg core.Value) (PageLoadParams, error
|
||||
if b {
|
||||
res.Driver = cdp.DriverName
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return res, nil
|
||||
@ -291,3 +303,53 @@ func parseHeader(header *values.Object) drivers.HTTPHeader {
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func parseViewport(value core.Value) (*drivers.Viewport, error) {
|
||||
if err := core.ValidateType(value, types.Object); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &drivers.Viewport{}
|
||||
|
||||
viewport := value.(*values.Object)
|
||||
|
||||
width, exists := viewport.Get(values.NewString("width"))
|
||||
|
||||
if exists {
|
||||
if err := core.ValidateType(width, types.Int); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.Width = int(values.ToInt(width))
|
||||
}
|
||||
|
||||
height, exists := viewport.Get(values.NewString("height"))
|
||||
|
||||
if exists {
|
||||
if err := core.ValidateType(height, types.Int); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res.Height = int(values.ToInt(height))
|
||||
}
|
||||
|
||||
mobile, exists := viewport.Get(values.NewString("mobile"))
|
||||
|
||||
if exists {
|
||||
res.Mobile = bool(values.ToBoolean(mobile))
|
||||
}
|
||||
|
||||
landscape, exists := viewport.Get(values.NewString("landscape"))
|
||||
|
||||
if exists {
|
||||
res.Landscape = bool(values.ToBoolean(landscape))
|
||||
}
|
||||
|
||||
scaleFactor, exists := viewport.Get(values.NewString("scaleFactor"))
|
||||
|
||||
if exists {
|
||||
res.ScaleFactor = float64(values.ToFloat(scaleFactor))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user