docstr: Verifies the callback requests on a browser-independent manner
  
  fr: FigureResamplerGUITests
      used for determining the browser-type.
  requests: List[Request]
      The captured requests of a SINGLE INTERACTION CALLBACK
  relayout_keys : List[str]
      The expected keys to be found in the relayout command
  n_updated_traces : int
      The expected amount of traces which will be updated.
docstr_tok: ["Verifies","the","callback","requests","on","a","browser-independent","manner","fr",":","FigureResamplerGUITests","used","for","determining","the","browser-type",".","requests",":","List","[","Request","]","The","captured","requests","of","a","SINGLE","INTERACTION","CALLBACK","relayout_keys",":","List","[","str","]","The","expected","keys","to","be","found","in","the","relayout","command","n_updated_traces",":","int","The","expected","amount","of","traces","which","will","be","updated","."]
code: def browser_independent_single_callback_request_assert(
      fr: FigureResamplerGUITests,
      relayout_keys: List[str],
      n_updated_traces: int,
  ):
      """Verifies the callback requests on a browser-independent manner
  
      fr: FigureResamplerGUITests
          used for determining the browser-type.
      requests: List[Request]
          The captured requests of a SINGLE INTERACTION CALLBACK
      relayout_keys : List[str]
          The expected keys to be found in the relayout command
      n_updated_traces : int
          The expected amount of traces which will be updated.
  
      """
      # First, filter the requests to only retain the relevant ones
      requests = RequestParser.filter_callback_requests(
          fr.get_requests()
      )
  
      browser_name = fr.driver.capabilities["browserName"]
      if "firefox" in browser_name:
          # There are 2 requests which are send
          # 1. first: changed-layout to server -> new data to back-end request
          # 2. the front-end relayout request
          assert len(requests) >= 1
          if len(requests) == 2:
              fetch_data_request, relayout_request = requests
              # RequestParser.assert_front_end_relayout_request(relayout_request)
          else:
              fetch_data_request = requests[0]
  
      elif "chrome" in browser_name:
          # for some, yet unknown reason, chrome does not seem to capture the
          # second front-end request.
          assert len(requests) == 1
          fetch_data_request = requests[0]
      else:
          raise ValueError(f"invalid browser name {browser_name}")
  
      # Validate the update-data-callback request
      RequestParser.assert_fetch_data_request(
          fetch_data_request,
          relayout_keys=relayout_keys,
          n_updated_traces=n_updated_traces,
      )
  
imports: from __future__ import annotations
  import json
  import time
  from typing import List, Union
  from selenium.webdriver.common.action_chains import ActionChains
  from selenium.webdriver.common.by import By
  from selenium.webdriver.support import expected_conditions
  from selenium.webdriver.support.ui import WebDriverWait
  from seleniumwire import webdriver
  from seleniumwire.request import Request
  from .utils import not_on_linux
label_desc: Use image node_id 4 for calling the RequestParser obj's underlying member method code with example usage: obj.browser_independent_single_callback_request_assert(fr, relayout_keys, n_updated_traces) without return types