S
S
Stanislav2019-08-30 16:54:03
PHP
Stanislav, 2019-08-30 16:54:03

Selenium: How to know if the browser window in a particular profile is already opened by someone else?

We have:
Code that works with the facebook-php-webdriver library. We work in many threads, the threads know something about each other, but for now we assume that they do not know anything.
Virtual machines running Selenium (in Java, the latest version) + chrome-webdriver (the version required for the current version of the browser) and to which our code goes with requests to visit certain pages and perform certain actions there.
Profiles for the Google Chrome browser , configured for certain specific tasks.
Situation:
There is an option that for one virtual machine in the same browser in the same profile (this is important!) First one copy of our code will come with this or that request. And he's trying to do something. At this point, two things can happen: either there was some error in the browser (or whatever), or our browser simply has not yet completed some task that we set for it.
And one way or another, we get the same situation - we have an already open browser profile, with a certain window open in it, and a certain page in it. And then a second copy of the code comes to us, which wants to open a certain page in the same profile and do something there.
Problem:
Under the described situation, the webdriverdoes not understand what to do, and behaves destructively, namely, it opens an empty tab three times, after which our php code instance is thrown with an error that the session could not be started and all that. As a result, as soon as we have such a situation, work with the profile is simply frozen, until the intervention of a living person.
Clarification:
We do not need to try to solve the described problem with php code. It is clear that it is possible to make a balancer that will limit the work with profiles at the run level of code instances, granting the right to one or another "one by one", but so far only native solutions are of interest.
What you are looking for:
An option when you can specify Selenium (webdriver?)that you need to hang the next request to the browser profile so that it has time to process it, and only then send the next request to the case.
Get a list of active profiles / sessions, so that they can be processed somehow later. Now we can get the session (sessionId) only after we have passed the moment of creating the webdriver, and it is not created just if one or another window is already open in the profile.
Code example:
which, as a result, cannot run twice (if it is started twice by different processes):

$caps           = DesiredCapabilities::chrome();
$chrome_options = new ChromeOptions();

$chrome_options->addArguments([
        "--user-data-dir=$user_data_dir",
        "--profile-directory=$profile",
]);

$caps->setCapability(ChromeOptions::CAPABILITY, $chrome_options);

// Вот здесь, если у нас уже как и написано выше в $caps установлено 
// использование определенного профиля браузера, мы не сможем еще раз 
// подключиться к нему, все это вызовет описанное выше поведение
// браузера и вебдрайвера

$this->webdriver = RemoteWebDriver::create(
    $service_url,
    $caps,
    $connection_timeout * 1000,
    $request_timeout * 1000
);

return $this->webdriver->getSessionID();

PS: yes, I know that this functionality was already requested in seleniumhq and was rejected. But maybe there are some workarounds to solve this problem. At the same time, if someone is not too clear about the question and there is a desire to go deeper, you can find the missing information at the link.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Stanislav, 2019-10-30
@stanislav-belichenko

In fact, no way. Everything was solved by balancing requests, when we do not send a new request until we are sure (almost, due to an excessive timeout) that the previous one did not work and the window did not close, just as the process did not end.
At the same time, it should be understood here that if we send a request to Selenium, for example, to go to a certain url (webdriver-> get (url)), then Selenium waits for this to actually happen, and then only control returns to us (of course, it is possible asynchronously try to do it, but the php-liba from FB does it that way). But when we send a request to the driver to close (I don’t remember exactly how it sounds, like close() or quit(), probably), then we don’t get any waiting, the request flies to the webdriver, and it sends a request to close to the browser, and Accordingly, with a heavy load on the machine, this request has allegedly already worked for us, but in reality the browser window is still closing, and then its process (s) are extinguished. And this time lag can reach tens of seconds.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question