Handling missing elements on login form in Selenium I try to improve my code so that I don't have to program a try - catch block all the time.

e.g. at the moment I have to write many codeblocks like this:

try {
    $login_feld = $SeleniumObj-&gt;driver-&gt;findElement(WebDriverBy::id("login_feld"));
} catch(NoSuchElementException $exception) {
    $SeleniumObj-&gt;setErrorMessage("1 ID login_feld does not exist.", $exception,  true, "login_field");
    break;
}
try {
    $password_field = $SeleniumObj-&gt;driver-&gt;findElement(WebDriverBy::id("password_field"));
} catch(NoSuchElementException $exception) {
    $SeleniumObj-&gt;setErrorMessage("1 ID password_field does not exist.", $exception,  true, "login_field");
    break;
}
try {
    $field3 = $SeleniumObj-&gt;driver-&gt;findElement(WebDriverBy::id("field3"));
} catch(NoSuchElementException $exception) {
    $SeleniumObj-&gt;setErrorMessage("1 ID field3 does not exist.", $exception,  true, "login_field");
    break;
}


My goal is to reduce this to one line.

Therefore I outsourced the whole driver-&gt;findElement(WebDriverBy::id("xy")); to a new function from the class Selenium called ById

/**
 * 
 * @param id $id
 * @param bool $takeScreenshot
 * @return void
 */
public function ById($id, $takeScreenshot=false)
{
    try {
        return $this-&gt;driver-&gt;findElement(WebDriverBy::id($id));

    } catch(NoSuchElementException $exception) {

        $this-&gt;setErrorMessage("ID '$id' does not exist.", $exception,  $takeScreenshot, $id);
        //break;  &lt;- does not work in this context
    }
}


Now theoretically I can code the whole block like this:

$login_feld = $SeleniumObj-&gt;ById('login_feld', true);
$password_field = $SeleniumObj-&gt;ById('password_field', true);
$field3 = $SeleniumObj-&gt;ById('field3', true);


However, one problem still persist. I can't call break in the exception block in the function ById, otherwise I get 


  break' not in the 'loop' or 'switch' context




Now to solve this I could instead return a status, e.g. false if the code reached in the exception block and then check this before proceeding 

/**
 * 
 * @param id $id
 * @param bool $takeScreenshot
 * @return void
 */
public function ById($id, $takeScreenshot=false)
{
    try {
        return $this-&gt;driver-&gt;findElement(WebDriverBy::id($id));

    } catch(NoSuchElementException $exception) {

        $this-&gt;setErrorMessage("ID '$id' does not exist.", $exception,  $takeScreenshot, $id);
        return false;
    }
}


-

$login_field = $SeleniumObj-&gt;ById('login_field', true);
if ($login_field == false) { break; }
$pw_field = $SeleniumObj-&gt;ById('pw_field', true);
if ($pw_field == false) { break; }
$field3 = $SeleniumObj-&gt;ById('field3', true);
if ($field3 == false) { break; }


But now I need two lines per block instead of one. 
Is it possible to improve this even further?
I don't understand what you are intending to do with break in your catch blocks to begin with.  Even in your first code example, you are not within a loop construct to where this makes sense.

In your new code, you should have method name begin with lower case (i.e. byId) as this is pretty much standard in PHP.  I don't really see what value this method is bringing though, as I would tend to agree with the post by @YourCommonSense that you might simplify your operation by using a looping construct.  However I might suggest you put the try-catch within the loop if your intent is to be able to engage in the try-catch for each element rather than for the collection of elements as a whole.

For example:

$elements = [
    'login_feld' =&gt; null,
    'password_field' =&gt; null,
    'field3' =&gt; null
];
foreach($elements as $id =&gt; $notUsed) {
    try {
        $elements[$id] = $SeleniumObj-&gt;driver-&gt;findElement(WebDriverBy::id($id));
    } catch (NoSuchElementException $e) {
        $SeleniumObj-&gt;setErrorMessage(
            '1 ID ' . $id . 'does not exist.',
            $e,
            true,
            $id
        );
        // if you want to break here, you now have proper loop context
        // break;
    }
}

// if successful, you can now access the elements from $elements array


This approach is scalable as you add more elements into your test cases, as you could just add new id keys into the element array and not worry about polluting your global namespace with a bunch of $[elementId] variables. You also now have the ability to simply look at the value stored at each key to determine if the element was found.  So for example, if you are going to perform a test action against a certain element, you can test for it like:

if(!is_null($elements['login_field'])) {
    // execute tests against element
} else {
    // log test fail
}


This approach might totally alleviate your need to break altogether, meaning you could now continue to execute your test suite even if one of the elements you expect to be present is missing.  You could just fail those particular tests relevant to the missing element.