Pcore

 view release on metacpan or  search on metacpan

lib/Pcore/API/Chrome.pm  view on Meta::CPAN

has listen        => '//127.0.0.1';
has user_data_dir => sub { P->file1->tempdir };
has useragent     => ();
has proxy         => ();

has _proc         => ();
has _proxy_server => ();

# https://chromedevtools.github.io/devtools-protocol/tot/
# https://peter.sh/experiments/chromium-command-line-switches/

# TODO test --ignore-certificate-errors

const our $CHECK_PORT_TIMEOUT => 0.1;
const our $CONNECT_TIMEOUT    => 10;

sub DESTROY ( $self ) {

    # term process group
    CORE::kill '-TERM', $self->{_proc}->{pid} if !$MSWIN && defined $self->{_proc};

    return;
}

around new => sub ( $orig, $self, %args ) {
    $args{bin} ||= $MSWIN ? "$ENV{'ProgramFiles(x86)'}/Google/Chrome/Application/chrome.exe" : '/usr/bin/google-chrome';

    my $user_args = delete $args{args};

    $self = $self->$orig(%args);

    $self->{listen} = P->net->parse_listen( $self->{listen} );

    if ( $self->{proxy} ) {
        $self->{_proxy_server} = Pcore::API::Proxy::Server->new;

        $self->set_proxy( $self->{proxy} );
    }

    my $cmd = [
        qq["$args{bin}"],

        "--remote-debugging-address=$self->{listen}->{host}",
        "--remote-debugging-port=$self->{listen}->{port}",

        '--disable-background-networking',
        '--disable-client-side-phishing-detection',
        '--disable-component-update',
        '--disable-hang-monitor',
        '--disable-prompt-on-repost',
        '--disable-sync',
        '--disable-web-resources',

        '--start-maximized',
        '--window-size=1280x720',

        '--disable-default-apps',
        '--no-default-browser-check',
        '--no-first-run',
        '--disable-infobars',
        '--disable-popup-blocking',
        '--disable-web-security',
        '--allow-running-insecure-content',

        # TODO socks currently may not work with http:80 requests
        # $self->{proxy} ? qq[--proxy-server="socks5://$self->{_proxy_server}->{listen}->{host_port}"] : (),
        $self->{proxy} ? qq[--proxy-server="$self->{_proxy_server}->{listen}->{host_port}"] : (),

        # logging
        # '--disable-logging',
        # '--log-level=0',

        # set user profile dir
        qq[--user-data-dir="$self->{user_data_dir}"],

        # required for run under docker
        '--no-sandbox',

        # user agent
        defined $self->{useragent} ? qq[--user-agent="$self->{useragent}"] : (),

        # headless mode
        $args{headless} || !$MSWIN ? ( '--headless', '--disable-gpu' ) : (),

        # user args
        $user_args ? $user_args->@* : (),

        # open "about:blank" by default
        # 'about:blank',

        # redirect STDERR under linux
        !$MSWIN ? '2>/dev/null' : (),
    ];

    $self->{_proc} = P->sys->run_proc( join( $SPACE, $cmd->@* ) );

    my $time = time + ( $args{timeout} // $CONNECT_TIMEOUT );

    while () {
        Coro::sleep($CHECK_PORT_TIMEOUT);

        last if P->net->check_port( $self->{listen}->{host}, $self->{listen}->{port}, $CHECK_PORT_TIMEOUT );

        die qq[Unable to connect to the google chrome on $self->{listen}->{host_port}] if time > $time;
    }

    return $self;
};

sub tabs ( $self ) {
    my $res = P->http->get("http://$self->{listen}->{host_port}/json");

    my $tabs = from_json $res->{data};

    for my $tab ( $tabs->@* ) {
        $tab = bless { chrome => $self, id => $tab->{id} }, 'Pcore::API::Chrome::Tab';
    }

    return res 200, $tabs;
}



( run in 1.077 second using v1.01-cache-2.11-cpan-364913b4093 )