docstr: Withholds checks for the relayout-data fetch request
  
  Parameters
  ----------
  data_request : Request
      The relayout data fetch request, with
      * Request body: the relayout changes
      * Response body: a list of dicts with first tiem
  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: ["Withholds","checks","for","the","relayout-data","fetch","request","Parameters","--","--","--","--","--","data_request",":","Request","The","relayout","data","fetch","request",",","with","*","Request","body",":","the","relayout","changes","*","Response","body",":","a","list","of","dicts","with","first","tiem","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 assert_fetch_data_request(
      data_request: Request,
      relayout_keys: List[str],
      n_updated_traces: int,
  ):
      """Withholds checks for the relayout-data fetch request
  
      Parameters
      ----------
      data_request : Request
          The relayout data fetch request, with
          * Request body: the relayout changes
          * Response body: a list of dicts with first tiem
      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.
  
      """
      fetch_data_body = json.loads(data_request.body)
      assert (
          "inputs" in fetch_data_body
          and len(fetch_data_body["inputs"]) == 1
      )
      # verify that the request is triggered by the relayoutData
      figure_id = "resample-figure"
      assert fetch_data_body["inputs"][0]["id"] == figure_id
      assert fetch_data_body["inputs"][0]["property"] == "relayoutData"
      assert all(
          k in fetch_data_body["inputs"][0]["value"]
          for k in relayout_keys
      )
      # verify that the response is a list of dicts
      fetch_data_response_body = json.loads(data_request.response.body)[
          "response"
      ]
      # convert the updateData to a list of dicts
      updateData = fetch_data_response_body[figure_id]["figure"][
          "operations"
      ]
      updated_traces = list(set(d["location"][1] for d in updateData))
  
      updated_x_keys = set(
          map(
              lambda d: d["location"][1],
              (filter(lambda x: x["location"][-1] == "x", updateData)),
          )
      )
      updated_y_keys = set(
          map(
              lambda d: d["location"][1],
              (filter(lambda x: x["location"][-1] == "y", updateData)),
          )
      )
  
      assert n_updated_traces == len(updated_traces)
  
      # verify that there are x and y updates for each trace
      assert (
          len(updated_x_keys) == len(updated_y_keys) == 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 2 for calling the RequestParser obj's underlying member method code with example usage: obj.assert_fetch_data_request(data_request, relayout_keys, n_updated_traces) without return types