Есть тести, где webdriver - ето singleton. Как реализовать паралельное тестирование ?

Webdriver instance - ето результат обвертки singletona и фабричного метода, соотвественно grid не запустишь с таким подходом.
Как бить ?
Знаю sauce labs сервиси запускают тести на разних конфигурациях, нужен ли для них такой же подход с ThreadLocal как у grid или оно просто запустит “копии” кода на разних инстансах енвайрмента ?

Сразу наперед, - тести конфигаються через xml файл , в котором прописан броузер на чем их запускать(chrome, ff, ios, android).

Оно запустит тесты на удаленных серверах. Но инстанс драйвера то хэндлится на вашей стороне. Вы лишь передаете конструктору драйвера url удаленного хаба с аксесс ключиком + капабилити. Пример от самих saucelabs:

private WebDriver driver;

    @Before
    public void setUp() throws Exception {
        // Choose the browser, version, and platform to test
        DesiredCapabilities capabilities = DesiredCapabilities.firefox();
        capabilities.setCapability("version", "5");
        capabilities.setCapability("platform", Platform.XP);
        // Create the connection to Sauce Labs to run the tests
        this.driver = new RemoteWebDriver(
                new URL("http://YOUR_USERNAME:YOUR_ACCESS_KEY@ondemand.saucelabs.com:80/wd/hub"),
                capabilities);
    }

В зависимости от капабилити, хаб найдет подходящий удаленный нод и будет перенаправлять туда ваши команды. Если ваша архитектура не позволяет запускать тесты параллельно, то придется заниматься рефакторингом. Думаю не стоит упоминать о важности продумывания архитектуры до начала разработки фреймворка?

Отвечая на ваш вопрос: при более или менее вменяемой архитектуре вам придется чуть подправить только лишь раннер и абстрактный пейдж, чтобы добиться поддержки масштабирования.

архитектуру я то продумал…рефакторить не очень много, только “запускалку” тестов и метод которий отдает драйвер, но я так понимаю мне нужно теперь ThreadLocal list драйверов хранить, чтоб например в listener-ах, где у меня драйвер используеться дернуть нужний мне поток с нужним инстансом(для скриншотов наприкмер) и теперь непонятно как будуть логи писаться паралельно и allure репорт собираться будет…)

Зачем вам ThreadLocal list драйверов? ThreadLocal привязывается к первому попросившему потоку. На N потоков будет свой собственный контейнер. Т.е. инстанс драйвера, помещенный в потокобезопасный контейнер, будет видим строго в пределах своего потока.

Allure формирует репорт постфактум на основании сгенерированных результирующих xml. Ему вообще без разницы, как вы запускаете ваши тесты.

та я ето понимаю, я просто думаю что возникнут проблеми в тех местах где я юзал getDriverInstance с фабрики которий возвращаеться синглоном.
Если откроеться 5 окон браузера, то нужно в разние моменти времени например брать скриншоти как раз драйвером…думаю там и начнуться косяки. Помню когда то я разпихивал driver - и в потоковий контейнер и написал простой get для добичи поточного драйвера с контейнера и так работало)

Какая разница сколько потоков будет дергать getDriverInstance, если каждый из них будет обращаться к своему собственному потокобезопасному инстансу?

private static final ThreadLocal<WebDriver> DRIVER = new ThreadLocal<>(); 

public static WebDriver getDriverInstance() {
    return DRIVER.get();
}

ну я про ето и говорю сообственно, что нужно ThreadLocal

Я думал может sauce labs проканает на синглтоне статичном и не нужно будет перепиливать