### Question:
ActionWithJSPreconditionBase implements ActionWithJSPrecondition, WebDriverAction { @Override public void execute(WebDriver driver, ReplayingState replayingState, EventSynchronizer eventSynchronizer) { String hashCodeToWaitFor = String.valueOf(getJSEventToWaitFor().hashCode()); logger.info("Condition {} has hashcode {}", getJSEventToWaitFor(), hashCodeToWaitFor); SynchronizationEvent synchronizationEvent = new JSPrecondition(hashCodeToWaitFor, eventSynchronizer, replayingState); try { eventSynchronizer.awaitUntil(synchronizationEvent); } catch (InterruptedException | TimeoutException e) { throw new WebDriverActionExecutionException("Exception while awaiting JS precondition", e, new InstanceBasedAutomationResultBuilder()); } executeAfterJSPreconditionHasBeenSatisfied(driver, replayingState, contextProvider); } protected  ActionWithJSPreconditionBase(SearchContextFunction contextProvider); @Override void execute(WebDriver driver, ReplayingState replayingState, EventSynchronizer eventSynchronizer); abstract void executeAfterJSPreconditionHasBeenSatisfied(WebDriver driver, ReplayingState replayingState, Function<SearchContext, SearchContext> contextProvider); @Override String getName();  }### Answer:
@Test public void lockCallsAWaitIfWaitingEventIsNotSatisfiedWhenSubmitted() throws InterruptedException, TimeoutException { String jsEvent = "jsEvent"; WebDriver driver = mock(WebDriver.class); SearchContextFunction contextProvider = webDriver1 -> driver; ActionWithJSPreconditionBase actionWithJSPreconditionBase = new ActionWithJSPreconditionBase(contextProvider) { @Override public void executeAfterJSPreconditionHasBeenSatisfied(WebDriver driver, ReplayingState replayingState, Function<SearchContext, SearchContext> contextProvider) { } @Override public String getName() { return null; } @Override public boolean expectsHttpRequest() { return false; } @Override public String getJSEventToWaitFor() { return jsEvent; } }; EventSynchronizer eventSynchronizer = mock(EventSynchronizer.class); ReplayingState replayingState = mock(ReplayingState.class); actionWithJSPreconditionBase.execute(driver, replayingState, eventSynchronizer); verify(eventSynchronizer).awaitUntil(any(SynchronizationEvent.class)); }
@Test public void lockDoesWaitIfWaitingEventIsNotSatisfiedWhenSubmitted() throws InterruptedException, TimeoutException { String jsEvent = "jsEvent"; WebDriver driver = mock(WebDriver.class); SearchContextFunction contextProvider = webDriver1 -> driver; ActionWithJSPreconditionBase actionWithJSPreconditionBase = new ActionWithJSPreconditionBase(contextProvider) { @Override public void executeAfterJSPreconditionHasBeenSatisfied(WebDriver driver, ReplayingState replayingState, Function<SearchContext, SearchContext> contextProvider) { } @Override public String getName() { return null; } @Override public boolean expectsHttpRequest() { return false; } @Override public String getJSEventToWaitFor() { return jsEvent; } }; EventSynchronizer eventSynchronizer = mock(EventSynchronizer.class); ReplayingState replayingState = mock(ReplayingState.class); when(replayingState.isSatisfied(jsEvent)).thenReturn(true); actionWithJSPreconditionBase.execute(driver, replayingState, eventSynchronizer); verify(eventSynchronizer).awaitUntil(any()); }