Repository: gradio-app/gradio
Pull request: [Integration Tests] Update a demo's config.json as part of integration test
# Description
When `pnpm test:browser` or `pnpm test:browser:full` is run from the `ui` the configs for each demo in the integration tests will be re-created.

Please include: 
* relevant motivation
* a summary of the change 
* which issue is fixed. 
* any additional dependencies that are required for this change.

Closes: # (issue)
#1937

# Checklist:

- [ ] I have performed a self-review of my own code
- [ ] My code follows the style guidelines of this project
- [ ] I have commented my code in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes


Problem statement:
[Integration Tests] Update a demo's config.json as part of integration test
### Describe the bug

The config.json for each demo used by the integration test needs to be manually updated by running `write_config.py`. This should be done as part of each integration test programatically. 

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Reproduction

N/A

### Screenshot

_No response_

### Logs

```shell
N/A
```


### System Info

```shell
N/A
```


### Severity

annoying

Hints from issue discussion:

Commit message: add script to create configs for test demos

Patch to review:
diff --git a/demo/blocks_inputs/config.json b/demo/blocks_inputs/config.json
index 5321604599..2af2202d90 100644
--- a/demo/blocks_inputs/config.json
+++ b/demo/blocks_inputs/config.json
@@ -1,5 +1,5 @@
 {
-  "version": "3.0.6",
+  "version": "3.1.4",
   "mode": "blocks",
   "dev_mode": true,
   "components": [
@@ -7,7 +7,7 @@
       "id": 1,
       "type": "textbox",
       "props": {
-        "lines": 5,
+        "lines": 2,
         "max_lines": 20,
         "value": "",
         "label": "Input",
@@ -24,7 +24,7 @@
         "lines": 1,
         "max_lines": 20,
         "value": "",
-        "label": "Output-Interactive",
+        "label": "Input 2",
         "show_label": true,
         "name": "textbox",
         "visible": true,
@@ -37,10 +37,9 @@
       "props": {
         "lines": 1,
         "max_lines": 20,
-        "value": "Hello friends\nhello friends\n\nHello friends\n\n",
+        "value": "",
         "label": "Output",
         "show_label": true,
-        "interactive": false,
         "name": "textbox",
         "visible": true,
         "style": {}
@@ -56,10 +55,128 @@
         "visible": true,
         "style": {}
       }
+    },
+    {
+      "id": 5,
+      "type": "row",
+      "props": {
+        "type": "row",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 6,
+      "type": "image",
+      "props": {
+        "image_mode": "RGB",
+        "source": "upload",
+        "tool": "editor",
+        "streaming": false,
+        "mirror_webcam": true,
+        "show_label": true,
+        "name": "image",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 7,
+      "type": "image",
+      "props": {
+        "image_mode": "RGB",
+        "source": "upload",
+        "tool": "editor",
+        "streaming": false,
+        "mirror_webcam": true,
+        "show_label": true,
+        "name": "image",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 8,
+      "type": "button",
+      "props": {
+        "value": "Mirror Image",
+        "variant": "secondary",
+        "name": "button",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 9,
+      "type": "markdown",
+      "props": {
+        "value": "<h2>Text Examples</h2>\n",
+        "name": "markdown",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 10,
+      "type": "dataset",
+      "props": {
+        "components": [
+          "textbox",
+          "textbox"
+        ],
+        "headers": [
+          "Input",
+          "Input 2"
+        ],
+        "samples": [
+          [
+            "hi",
+            "Adam"
+          ],
+          [
+            "hello",
+            "Eve"
+          ]
+        ],
+        "type": "index",
+        "name": "dataset",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 11,
+      "type": "markdown",
+      "props": {
+        "value": "<h2>Image Examples</h2>\n",
+        "name": "markdown",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 12,
+      "type": "dataset",
+      "props": {
+        "components": [
+          "image"
+        ],
+        "headers": [],
+        "samples": [
+          [
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/blocks_inputs/lion.jpg"
+          ]
+        ],
+        "type": "index",
+        "name": "dataset",
+        "visible": true,
+        "style": {}
+      }
     }
   ],
   "theme": "default",
   "css": null,
+  "title": "Gradio",
   "enable_queue": false,
   "layout": {
     "id": 0,
@@ -75,6 +192,32 @@
       },
       {
         "id": 4
+      },
+      {
+        "id": 5,
+        "children": [
+          {
+            "id": 6
+          },
+          {
+            "id": 7
+          }
+        ]
+      },
+      {
+        "id": 8
+      },
+      {
+        "id": 9
+      },
+      {
+        "id": 10
+      },
+      {
+        "id": 11
+      },
+      {
+        "id": 12
       }
     ]
   },
@@ -85,15 +228,79 @@
       ],
       "trigger": "click",
       "inputs": [
-        1
+        1,
+        2
       ],
       "outputs": [
-        2
+        3
+      ],
+      "backend_fn": true,
+      "js": null,
+      "status_tracker": null,
+      "queue": null,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
+    },
+    {
+      "targets": [
+        8
+      ],
+      "trigger": "click",
+      "inputs": [
+        6
+      ],
+      "outputs": [
+        7
+      ],
+      "backend_fn": true,
+      "js": null,
+      "status_tracker": null,
+      "queue": null,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
+    },
+    {
+      "targets": [
+        10
+      ],
+      "trigger": "click",
+      "inputs": [
+        10
+      ],
+      "outputs": [
+        1,
+        2,
+        3
+      ],
+      "backend_fn": true,
+      "js": null,
+      "status_tracker": null,
+      "queue": false,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
+    },
+    {
+      "targets": [
+        12
+      ],
+      "trigger": "click",
+      "inputs": [
+        12
+      ],
+      "outputs": [
+        6,
+        7
       ],
       "backend_fn": true,
       "js": null,
       "status_tracker": null,
-      "queue": null
+      "queue": false,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
     }
   ]
 }
\ No newline at end of file
diff --git a/demo/blocks_kinematics/config.json b/demo/blocks_kinematics/config.json
index 34aa00955e..bd73c06cdb 100644
--- a/demo/blocks_kinematics/config.json
+++ b/demo/blocks_kinematics/config.json
@@ -1,5 +1,5 @@
 {
-  "version": "3.0.6",
+  "version": "3.1.4",
   "mode": "blocks",
   "dev_mode": true,
   "components": [
@@ -76,6 +76,7 @@
   ],
   "theme": "default",
   "css": null,
+  "title": "Gradio",
   "enable_queue": false,
   "layout": {
     "id": 0,
@@ -118,7 +119,10 @@
       "backend_fn": true,
       "js": null,
       "status_tracker": null,
-      "queue": null
+      "queue": null,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
     }
   ]
 }
\ No newline at end of file
diff --git a/demo/blocks_page_load/config.json b/demo/blocks_page_load/config.json
index 3f8f7159d4..ed57c2c198 100644
--- a/demo/blocks_page_load/config.json
+++ b/demo/blocks_page_load/config.json
@@ -1,5 +1,7 @@
 {
+  "version": "3.1.4",
   "mode": "blocks",
+  "dev_mode": true,
   "components": [
     {
       "id": 1,
@@ -7,11 +9,12 @@
       "props": {
         "lines": 1,
         "max_lines": 20,
-        "default_value": "Frank",
+        "value": "Frank",
         "label": "Name",
         "show_label": true,
         "name": "textbox",
-        "css": {}
+        "visible": true,
+        "style": {}
       }
     },
     {
@@ -20,15 +23,18 @@
       "props": {
         "lines": 1,
         "max_lines": 20,
-        "default_value": "",
+        "value": "",
         "label": "Output",
         "show_label": true,
         "name": "textbox",
-        "css": {}
+        "visible": true,
+        "style": {}
       }
     }
   ],
   "theme": "default",
+  "css": null,
+  "title": "Gradio",
   "enable_queue": false,
   "layout": {
     "id": 0,
@@ -51,8 +57,13 @@
       "outputs": [
         2
       ],
+      "backend_fn": true,
+      "js": false,
       "status_tracker": null,
-      "queue": null
+      "queue": null,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
     }
   ]
 }
\ No newline at end of file
diff --git a/demo/blocks_xray/config.json b/demo/blocks_xray/config.json
index f4153b9097..d46cad7660 100644
--- a/demo/blocks_xray/config.json
+++ b/demo/blocks_xray/config.json
@@ -1,5 +1,5 @@
 {
-  "version": "3.1.1\n",
+  "version": "3.1.4",
   "mode": "blocks",
   "dev_mode": true,
   "components": [
@@ -280,11 +280,20 @@
       "show_progress": true,
       "documentation": [
         [
-          null,
-          null
+          [
+            "list of selected choices",
+            "List[str]"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ]
         ],
         [
-          null
+          [
+            "JSON output",
+            "Dict | List | None"
+          ]
         ]
       ]
     },
@@ -309,11 +318,20 @@
       "show_progress": true,
       "documentation": [
         [
-          null,
-          null
+          [
+            "list of selected choices",
+            "List[str]"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ]
         ],
         [
-          null
+          [
+            "JSON output",
+            "Dict | List | None"
+          ]
         ]
       ]
     },
diff --git a/demo/input-output/config.json b/demo/input-output/config.json
deleted file mode 100644
index f264101b26..0000000000
--- a/demo/input-output/config.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "mode": "blocks",
-  "components": [
-    {
-      "id": 1,
-      "type": "textbox",
-      "props": {
-        "lines": 1,
-        "placeholder": null,
-        "value": "",
-        "name": "textbox",
-        "label": "Input-Output",
-        "css": {},
-        "interactive": null
-      }
-    },
-    {
-      "id": 2,
-      "type": "button",
-      "props": {
-        "value": "Run",
-        "name": "button",
-        "label": null,
-        "css": {},
-        "interactive": null
-      }
-    }
-  ],
-  "theme": "default",
-  "layout": {
-    "id": 0,
-    "children": [
-      {
-        "id": 1
-      },
-      {
-        "id": 2
-      }
-    ]
-  },
-  "dependencies": [
-    {
-      "targets": [2],
-      "trigger": "click",
-      "inputs": [1],
-      "outputs": [1],
-      "queue": false
-    }
-  ]
-}
diff --git a/demo/input_output/config.json b/demo/input_output/config.json
new file mode 100644
index 0000000000..8cff5c5996
--- /dev/null
+++ b/demo/input_output/config.json
@@ -0,0 +1,68 @@
+{
+  "version": "3.1.4",
+  "mode": "blocks",
+  "dev_mode": true,
+  "components": [
+    {
+      "id": 1,
+      "type": "textbox",
+      "props": {
+        "lines": 1,
+        "max_lines": 20,
+        "value": "",
+        "label": "Input-Output",
+        "show_label": true,
+        "name": "textbox",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 2,
+      "type": "button",
+      "props": {
+        "value": "Run",
+        "variant": "secondary",
+        "name": "button",
+        "visible": true,
+        "style": {}
+      }
+    }
+  ],
+  "theme": "default",
+  "css": null,
+  "title": "Gradio",
+  "enable_queue": false,
+  "layout": {
+    "id": 0,
+    "children": [
+      {
+        "id": 1
+      },
+      {
+        "id": 2
+      }
+    ]
+  },
+  "dependencies": [
+    {
+      "targets": [
+        2
+      ],
+      "trigger": "click",
+      "inputs": [
+        1
+      ],
+      "outputs": [
+        1
+      ],
+      "backend_fn": true,
+      "js": null,
+      "status_tracker": null,
+      "queue": null,
+      "api_name": null,
+      "scroll_to_output": false,
+      "show_progress": true
+    }
+  ]
+}
\ No newline at end of file
diff --git a/demo/input-output/run.py b/demo/input_output/run.py
similarity index 100%
rename from demo/input-output/run.py
rename to demo/input_output/run.py
diff --git a/demo/kitchen_sink/config.json b/demo/kitchen_sink/config.json
index 416a4ed813..56a6f02e1c 100644
--- a/demo/kitchen_sink/config.json
+++ b/demo/kitchen_sink/config.json
@@ -1,10 +1,10 @@
 {
-  "version": "3.0.16\n",
-  "mode": "blocks",
+  "version": "3.1.4",
+  "mode": "interface",
   "dev_mode": true,
   "components": [
     {
-      "id": 26,
+      "id": 33,
       "type": "markdown",
       "props": {
         "value": "<h1 style='text-align: center; margin-bottom: 1rem'>Kitchen Sink</h1>",
@@ -14,7 +14,7 @@
       }
     },
     {
-      "id": 27,
+      "id": 34,
       "type": "markdown",
       "props": {
         "value": "<p>Try out all the components!</p>",
@@ -24,7 +24,7 @@
       }
     },
     {
-      "id": 28,
+      "id": 35,
       "type": "row",
       "props": {
         "type": "row",
@@ -36,7 +36,7 @@
       }
     },
     {
-      "id": 29,
+      "id": 36,
       "type": "column",
       "props": {
         "type": "column",
@@ -46,7 +46,7 @@
       }
     },
     {
-      "id": 30,
+      "id": 37,
       "type": "column",
       "props": {
         "type": "column",
@@ -184,7 +184,6 @@
           "bar",
           "baz"
         ],
-        "value": "foo",
         "label": "Dropdown",
         "show_label": true,
         "name": "dropdown",
@@ -200,6 +199,7 @@
         "source": "upload",
         "tool": "editor",
         "streaming": false,
+        "mirror_webcam": true,
         "label": "Image",
         "show_label": true,
         "name": "image",
@@ -215,6 +215,7 @@
         "source": "upload",
         "tool": "select",
         "streaming": false,
+        "mirror_webcam": true,
         "label": "Image w/ Cropper",
         "show_label": true,
         "name": "image",
@@ -230,6 +231,7 @@
         "source": "canvas",
         "tool": "editor",
         "streaming": false,
+        "mirror_webcam": true,
         "label": "Sketchpad",
         "show_label": true,
         "name": "image",
@@ -245,6 +247,7 @@
         "source": "webcam",
         "tool": "editor",
         "streaming": false,
+        "mirror_webcam": true,
         "label": "Webcam",
         "show_label": true,
         "name": "image",
@@ -257,6 +260,7 @@
       "type": "video",
       "props": {
         "source": "upload",
+        "mirror_webcam": true,
         "label": "Video",
         "show_label": true,
         "name": "video",
@@ -291,7 +295,85 @@
       }
     },
     {
-      "id": 31,
+      "id": 16,
+      "type": "file",
+      "props": {
+        "file_count": "single",
+        "label": "File",
+        "show_label": true,
+        "name": "file",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 17,
+      "type": "dataframe",
+      "props": {
+        "headers": [
+          "Name",
+          "Age",
+          "Gender"
+        ],
+        "datatype": [
+          "str",
+          "str",
+          "str"
+        ],
+        "row_count": [
+          1,
+          "dynamic"
+        ],
+        "col_count": [
+          3,
+          "dynamic"
+        ],
+        "value": {
+          "headers": [
+            "Name",
+            "Age",
+            "Gender"
+          ],
+          "data": [
+            [
+              "",
+              "",
+              ""
+            ]
+          ]
+        },
+        "max_rows": 20,
+        "overflow_row_behaviour": "paginate",
+        "wrap": false,
+        "label": "Dataframe",
+        "show_label": true,
+        "name": "dataframe",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 18,
+      "type": "timeseries",
+      "props": {
+        "x": "time",
+        "y": [
+          "price",
+          "value"
+        ],
+        "colors": [
+          "pink",
+          "purple"
+        ],
+        "label": "df2",
+        "show_label": true,
+        "name": "timeseries",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 38,
       "type": "row",
       "props": {
         "type": "row",
@@ -302,7 +384,7 @@
       }
     },
     {
-      "id": 32,
+      "id": 39,
       "type": "button",
       "props": {
         "value": "Clear",
@@ -313,7 +395,7 @@
       }
     },
     {
-      "id": 33,
+      "id": 40,
       "type": "button",
       "props": {
         "value": "Submit",
@@ -324,7 +406,7 @@
       }
     },
     {
-      "id": 34,
+      "id": 41,
       "type": "column",
       "props": {
         "type": "column",
@@ -334,7 +416,7 @@
       }
     },
     {
-      "id": 35,
+      "id": 42,
       "type": "statustracker",
       "props": {
         "cover_container": true,
@@ -344,7 +426,7 @@
       }
     },
     {
-      "id": 16,
+      "id": 19,
       "type": "textbox",
       "props": {
         "lines": 1,
@@ -359,7 +441,7 @@
       }
     },
     {
-      "id": 17,
+      "id": 20,
       "type": "label",
       "props": {
         "label": "Label",
@@ -371,7 +453,7 @@
       }
     },
     {
-      "id": 18,
+      "id": 21,
       "type": "audio",
       "props": {
         "source": "upload",
@@ -385,13 +467,14 @@
       }
     },
     {
-      "id": 19,
+      "id": 22,
       "type": "image",
       "props": {
         "image_mode": "RGB",
         "source": "upload",
         "tool": "editor",
         "streaming": false,
+        "mirror_webcam": true,
         "label": "Image",
         "show_label": true,
         "interactive": false,
@@ -401,10 +484,11 @@
       }
     },
     {
-      "id": 20,
+      "id": 23,
       "type": "video",
       "props": {
         "source": "upload",
+        "mirror_webcam": true,
         "label": "Video",
         "show_label": true,
         "interactive": false,
@@ -414,7 +498,7 @@
       }
     },
     {
-      "id": 21,
+      "id": 24,
       "type": "highlightedtext",
       "props": {
         "color_map": {
@@ -431,7 +515,7 @@
       }
     },
     {
-      "id": 22,
+      "id": 25,
       "type": "highlightedtext",
       "props": {
         "show_legend": true,
@@ -444,7 +528,7 @@
       }
     },
     {
-      "id": 23,
+      "id": 26,
       "type": "json",
       "props": {
         "label": "JSON",
@@ -456,7 +540,7 @@
       }
     },
     {
-      "id": 24,
+      "id": 27,
       "type": "html",
       "props": {
         "value": "",
@@ -469,7 +553,131 @@
       }
     },
     {
-      "id": 36,
+      "id": 28,
+      "type": "file",
+      "props": {
+        "file_count": "single",
+        "label": "File",
+        "show_label": true,
+        "interactive": false,
+        "name": "file",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 29,
+      "type": "dataframe",
+      "props": {
+        "headers": [
+          1,
+          2,
+          3
+        ],
+        "datatype": [
+          "str",
+          "str",
+          "str"
+        ],
+        "row_count": [
+          1,
+          "dynamic"
+        ],
+        "col_count": [
+          3,
+          "dynamic"
+        ],
+        "value": {
+          "headers": [
+            1,
+            2,
+            3
+          ],
+          "data": [
+            [
+              "",
+              "",
+              ""
+            ]
+          ]
+        },
+        "max_rows": 20,
+        "overflow_row_behaviour": "paginate",
+        "wrap": false,
+        "label": "Dataframe",
+        "show_label": true,
+        "interactive": false,
+        "name": "dataframe",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 30,
+      "type": "dataframe",
+      "props": {
+        "headers": [
+          1,
+          2,
+          3
+        ],
+        "datatype": [
+          "str",
+          "str",
+          "str"
+        ],
+        "row_count": [
+          1,
+          "dynamic"
+        ],
+        "col_count": [
+          3,
+          "dynamic"
+        ],
+        "value": {
+          "headers": [
+            1,
+            2,
+            3
+          ],
+          "data": [
+            [
+              "",
+              "",
+              ""
+            ]
+          ]
+        },
+        "max_rows": 20,
+        "overflow_row_behaviour": "paginate",
+        "wrap": false,
+        "label": "Numpy",
+        "show_label": true,
+        "interactive": false,
+        "name": "dataframe",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 31,
+      "type": "timeseries",
+      "props": {
+        "x": "time",
+        "y": [
+          "price",
+          "value"
+        ],
+        "label": "Timeseries",
+        "show_label": true,
+        "interactive": false,
+        "name": "timeseries",
+        "visible": true,
+        "style": {}
+      }
+    },
+    {
+      "id": 43,
       "type": "row",
       "props": {
         "type": "row",
@@ -480,7 +688,7 @@
       }
     },
     {
-      "id": 37,
+      "id": 44,
       "type": "button",
       "props": {
         "value": "Flag",
@@ -491,7 +699,7 @@
       }
     },
     {
-      "id": 38,
+      "id": 45,
       "type": "dataset",
       "props": {
         "components": [
@@ -510,7 +718,10 @@
           "image",
           "video",
           "audio",
-          "audio"
+          "audio",
+          "file",
+          "dataframe",
+          "timeseries"
         ],
         "headers": [
           "Textbox",
@@ -528,7 +739,10 @@
           "Webcam",
           "Video",
           "Audio",
-          "Microphone"
+          "Microphone",
+          "File",
+          "Dataframe",
+          "df2"
         ],
         "samples": [
           [
@@ -549,7 +763,22 @@
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
-            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
+            [
+              [
+                1,
+                2,
+                3
+              ],
+              [
+                3,
+                4,
+                5
+              ]
+            ],
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
           ],
           [
             "the quick brown fox",
@@ -569,7 +798,22 @@
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
-            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
+            [
+              [
+                1,
+                2,
+                3
+              ],
+              [
+                3,
+                4,
+                5
+              ]
+            ],
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
           ],
           [
             "the quick brown fox",
@@ -589,7 +833,22 @@
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cheetah1.jpg",
             "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/world.mp4",
-            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav"
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/cantina.wav",
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/titanic.csv",
+            [
+              [
+                1,
+                2,
+                3
+              ],
+              [
+                3,
+                4,
+                5
+              ]
+            ],
+            "/Users/dawoodkhan/Desktop/Developer/gradio/demo/kitchen_sink/files/time.csv"
           ]
         ],
         "type": "index",
@@ -599,7 +858,7 @@
       }
     },
     {
-      "id": 39,
+      "id": 46,
       "type": "markdown",
       "props": {
         "value": "<p>Learn more about <a href=\"http://gradio.app\">Gradio</a></p>",
@@ -611,24 +870,25 @@
   ],
   "theme": "default",
   "css": null,
+  "title": "Kitchen Sink",
   "enable_queue": false,
   "layout": {
-    "id": 25,
+    "id": 32,
     "children": [
       {
-        "id": 26
+        "id": 33
       },
       {
-        "id": 27
+        "id": 34
       },
       {
-        "id": 28,
+        "id": 35,
         "children": [
           {
-            "id": 29,
+            "id": 36,
             "children": [
               {
-                "id": 30,
+                "id": 37,
                 "children": [
                   {
                     "id": 0
@@ -677,36 +937,36 @@
                   },
                   {
                     "id": 15
+                  },
+                  {
+                    "id": 16
+                  },
+                  {
+                    "id": 17
+                  },
+                  {
+                    "id": 18
                   }
                 ]
               },
               {
-                "id": 31,
+                "id": 38,
                 "children": [
                   {
-                    "id": 32
+                    "id": 39
                   },
                   {
-                    "id": 33
+                    "id": 40
                   }
                 ]
               }
             ]
           },
           {
-            "id": 34,
+            "id": 41,
             "children": [
               {
-                "id": 35
-              },
-              {
-                "id": 16
-              },
-              {
-                "id": 17
-              },
-              {
-                "id": 18
+                "id": 42
               },
               {
                 "id": 19
@@ -727,10 +987,31 @@
                 "id": 24
               },
               {
-                "id": 36,
+                "id": 25
+              },
+              {
+                "id": 26
+              },
+              {
+                "id": 27
+              },
+              {
+                "id": 28
+              },
+              {
+                "id": 29
+              },
+              {
+                "id": 30
+              },
+              {
+                "id": 31
+              },
+              {
+                "id": 43,
                 "children": [
                   {
-                    "id": 37
+                    "id": 44
                   }
                 ]
               }
@@ -739,17 +1020,17 @@
         ]
       },
       {
-        "id": 38
+        "id": 45
       },
       {
-        "id": 39
+        "id": 46
       }
     ]
   },
   "dependencies": [
     {
       "targets": [
-        33
+        40
       ],
       "trigger": "click",
       "inputs": [
@@ -768,61 +1049,171 @@
         12,
         13,
         14,
-        15
-      ],
-      "outputs": [
+        15,
         16,
         17,
-        18,
+        18
+      ],
+      "outputs": [
         19,
         20,
         21,
         22,
         23,
-        24
+        24,
+        25,
+        26,
+        27,
+        28,
+        29,
+        30,
+        31
       ],
       "backend_fn": true,
       "js": null,
-      "status_tracker": 35,
+      "status_tracker": 42,
       "queue": null,
       "api_name": "predict",
       "scroll_to_output": true,
       "show_progress": true,
       "documentation": [
         [
-          "(str): text",
-          "(str): text",
-          "(float | None): numeric input",
-          "(number): numeric input",
-          "(number): numeric input",
-          "(bool): boolean input",
-          "(List[str]): list of selected choices",
-          "(str): selected choice",
-          "(str): selected choice",
-          "(str): base64 url data",
-          "(str): base64 url data",
-          "(str): base64 url data",
-          "(str): base64 url data",
-          "(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property",
-          "(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property",
-          "(Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property"
+          [
+            "text",
+            "str | None"
+          ],
+          [
+            "text",
+            "str | None"
+          ],
+          [
+            "numeric input",
+            "float | None"
+          ],
+          [
+            "numeric input",
+            "float"
+          ],
+          [
+            "numeric input",
+            "float"
+          ],
+          [
+            "boolean input",
+            "bool"
+          ],
+          [
+            "list of selected choices",
+            "List[str]"
+          ],
+          [
+            "selected choice",
+            "str"
+          ],
+          [
+            "selected choice",
+            "str"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ],
+          [
+            "base64 url data, or (if tool == \"sketch) a dict of image and mask base64 url data",
+            "str | Dict"
+          ],
+          [
+            "JSON object with filename as 'name' property and base64 data as 'data' property",
+            "Dict[str, str] | None"
+          ],
+          [
+            "JSON object with filename as 'name' property and base64 data as 'data' property",
+            "Dict[str, str] | None"
+          ],
+          [
+            "JSON object with filename as 'name' property and base64 data as 'data' property",
+            "Dict[str, str] | None"
+          ],
+          [
+            "List of JSON objects with filename as 'name' property and base64 data as 'data' property",
+            "List[Dict[str, str]] | None"
+          ],
+          [
+            "2D array of str, numeric, or bool data",
+            "DataframeData"
+          ],
+          [
+            "Dict with keys 'data': 2D array of str, numeric, or bool data, 'headers': list of strings for header names, 'range': optional two element list designating start of end of subrange.",
+            "Dict | None"
+          ]
         ],
         [
-          "(str | None): text",
-          "(Dict[label: str, confidences: List[Dict[label: str, confidence: number]]]): Object with key 'label' representing primary label, and key 'confidences' representing a list of label-confidence pairs",
-          "(str): base64 url data",
-          "(str): base64 url data",
-          "(str): base64 url data",
-          "(List[Tuple[str, str | number | None]]): List of (word, category) tuples",
-          "(List[Tuple[str, str | number | None]]): List of (word, category) tuples",
-          "(Dict | List): JSON output",
-          null
+          [
+            "text",
+            "str | None"
+          ],
+          [
+            "Object with key 'label' representing primary label, and key 'confidences' representing a list of label-confidence pairs",
+            "Dict | None"
+          ],
+          [
+            "base64 url data",
+            "str"
+          ],
+          [
+            "base64 url data",
+            "str"
+          ],
+          [
+            "base64 url data",
+            "str"
+          ],
+          [
+            "List of (word, category) tuples",
+            "Optional[List[Tuple[str, str | float | None]]]"
+          ],
+          [
+            "List of (word, category) tuples",
+            "Optional[List[Tuple[str, str | float | None]]]"
+          ],
+          [
+            "JSON output",
+            "Dict | List | None"
+          ],
+          [
+            null,
+            "None"
+          ],
+          [
+            "JSON object with key 'name' for filename, 'data' for base64 url, and 'size' for filesize in bytes",
+            "Dict"
+          ],
+          [
+            "JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
+            "Dict"
+          ],
+          [
+            "JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
+            "Dict"
+          ],
+          [
+            "JSON object with key 'headers' for list of header names, 'data' for 2D array of string or numeric data",
+            "Dict"
+          ]
         ]
       ]
     },
     {
       "targets": [
-        32
+        39
       ],
       "trigger": "click",
       "inputs": [],
@@ -852,10 +1243,17 @@
         22,
         23,
         24,
-        30
+        25,
+        26,
+        27,
+        28,
+        29,
+        30,
+        31,
+        37
       ],
       "backend_fn": false,
-      "js": "() => [\"\", \"\", null, 15, 0, null, [], \"baz\", \"foo\", null, null, null, null, null, null, null, \"\", null, null, null, null, null, null, null, null, {\"variant\": null, \"visible\": true, \"__type__\": \"update\"}]\n                ",
+      "js": "() => [\"\", \"\", null, 15, 0, null, [], \"baz\", null, null, null, null, null, null, null, null, null, null, null, \"\", null, null, null, null, null, null, null, null, null, null, null, null, {\"variant\": null, \"visible\": true, \"__type__\": \"update\"}]\n                ",
       "status_tracker": null,
       "queue": null,
       "api_name": null,
@@ -864,7 +1262,7 @@
     },
     {
       "targets": [
-        37
+        44
       ],
       "trigger": "click",
       "inputs": [
@@ -892,7 +1290,14 @@
         21,
         22,
         23,
-        24
+        24,
+        25,
+        26,
+        27,
+        28,
+        29,
+        30,
+        31
       ],
       "outputs": [],
       "backend_fn": true,
@@ -905,11 +1310,11 @@
     },
     {
       "targets": [
-        38
+        45
       ],
       "trigger": "click",
       "inputs": [
-        38
+        45
       ],
       "outputs": [
         0,
@@ -927,7 +1332,10 @@
         12,
         13,
         14,
-        15
+        15,
+        16,
+        17,
+        18
       ],
       "backend_fn": true,
       "js": null,
diff --git a/demo/kitchen_sink/run.py b/demo/kitchen_sink/run.py
index 6b9e5147be..ee77c886a8 100755
--- a/demo/kitchen_sink/run.py
+++ b/demo/kitchen_sink/run.py
@@ -73,7 +73,7 @@ def fn(
             (".", 0),
         ]
         + [(f"test", x / 10) for x in range(-10, 10)],  # HighlightedText
-        json.loads(JSONOBJ),  # JSON
+        json.loads(JSONOBJ),  # JSONåå
         "<button style='background-color: red'>Click Me: "
         + radio
         + "</button>",  # HTML
diff --git a/demo/outbreak_forecast/config.json b/demo/outbreak_forecast/config.json
index 64bf6b2321..b9ceff7e07 100644
--- a/demo/outbreak_forecast/config.json
+++ b/demo/outbreak_forecast/config.json
@@ -1,5 +1,5 @@
 {
-  "version": "3.1.1\n",
+  "version": "3.1.4",
   "mode": "interface",
   "dev_mode": true,
   "components": [
@@ -358,14 +358,32 @@
       "show_progress": true,
       "documentation": [
         [
-          null,
-          null,
-          null,
-          null,
-          null
+          [
+            "selected choice",
+            "str"
+          ],
+          [
+            "numeric input",
+            "float"
+          ],
+          [
+            "selected choice",
+            "str"
+          ],
+          [
+            "list of selected choices",
+            "List[str]"
+          ],
+          [
+            "boolean input",
+            "bool"
+          ]
         ],
         [
-          null
+          [
+            "plot type mapped to plot base64 data",
+            "Dict[str, str] | None"
+          ]
         ]
       ]
     },
diff --git a/ui/packages/app/package.json b/ui/packages/app/package.json
index ede50d745f..8622a146f3 100644
--- a/ui/packages/app/package.json
+++ b/ui/packages/app/package.json
@@ -8,7 +8,7 @@
 		"build:website": "vite build --mode production:website --emptyOutDir",
 		"build:local": "vite build --mode production:local --emptyOutDir",
 		"preview": "vite preview",
-		"test:browser": "pnpm exec playwright test test/ --config=../../playwright.config.js",
+		"test:browser": "pnpm exec python test/create_demo_configs.py && pnpm exec playwright test test/ --config=../../playwright.config.js",
 		"test:browser:debug": "pnpm exec playwright test test/ --debug --config=../../playwright.config.js"
 	},
 	"dependencies": {
diff --git a/ui/packages/app/test/blocks-inputs.spec.ts b/ui/packages/app/test/blocks_inputs.spec.ts
similarity index 100%
rename from ui/packages/app/test/blocks-inputs.spec.ts
rename to ui/packages/app/test/blocks_inputs.spec.ts
diff --git a/ui/packages/app/test/blocks-kinematics.spec.ts b/ui/packages/app/test/blocks_kinematics.spec.ts
similarity index 100%
rename from ui/packages/app/test/blocks-kinematics.spec.ts
rename to ui/packages/app/test/blocks_kinematics.spec.ts
diff --git a/ui/packages/app/test/blocks-page-load.spec.ts b/ui/packages/app/test/blocks_page_load.spec.ts
similarity index 100%
rename from ui/packages/app/test/blocks-page-load.spec.ts
rename to ui/packages/app/test/blocks_page_load.spec.ts
diff --git a/ui/packages/app/test/blocks-xray.spec.ts b/ui/packages/app/test/blocks_xray.spec.ts
similarity index 100%
rename from ui/packages/app/test/blocks-xray.spec.ts
rename to ui/packages/app/test/blocks_xray.spec.ts
diff --git a/ui/packages/app/test/create_demo_configs.py b/ui/packages/app/test/create_demo_configs.py
new file mode 100644
index 0000000000..0cf4a45d9b
--- /dev/null
+++ b/ui/packages/app/test/create_demo_configs.py
@@ -0,0 +1,10 @@
+import os
+import subprocess
+
+for f in os.listdir(os.path.dirname(__file__)):
+    if ".spec.ts" in f:
+        split_tup = f.split(".")
+        command = f'python ../../../../demo/write_config.py {split_tup[0]} ../../../../demo/{split_tup[0]}/config.json'
+        process = subprocess.Popen(command.split(), stdout=subprocess.PIPE, cwd=os.path.dirname(__file__))
+        output, error = process.communicate()
+    
\ No newline at end of file
diff --git a/ui/packages/app/test/input-output.spec.ts b/ui/packages/app/test/input_output.spec.ts
similarity index 96%
rename from ui/packages/app/test/input-output.spec.ts
rename to ui/packages/app/test/input_output.spec.ts
index 9ce53b543f..5923c1b1a5 100644
--- a/ui/packages/app/test/input-output.spec.ts
+++ b/ui/packages/app/test/input_output.spec.ts
@@ -26,7 +26,7 @@ function mock_api(page: Page, body: Array<unknown>) {
 }
 
 test("a component acts as both input and output", async ({ page }) => {
-	await mock_demo(page, "input-output");
+	await mock_demo(page, "input_output");
 	await mock_api(page, [["tset"]]);
 	await page.goto("http://localhost:3000");
 
diff --git a/ui/packages/app/test/kitchen-sink.spec.ts b/ui/packages/app/test/kitchen_sink.spec.ts
similarity index 100%
rename from ui/packages/app/test/kitchen-sink.spec.ts
rename to ui/packages/app/test/kitchen_sink.spec.ts
diff --git a/ui/packages/app/test/outbreak-forecast.spec.ts b/ui/packages/app/test/outbreak_forecast.spec.ts
similarity index 100%
rename from ui/packages/app/test/outbreak-forecast.spec.ts
rename to ui/packages/app/test/outbreak_forecast.spec.ts


Code review comments:
diff_hunk: @@ -73,7 +73,7 @@ def fn(
             (".", 0),
         ]
         + [(f"test", x / 10) for x in range(-10, 10)],  # HighlightedText
-        json.loads(JSONOBJ),  # JSON
+        json.loads(JSONOBJ),  # JSONåå
path: demo/kitchen_sink/run.py
text: @user1:
Weird symbols showing up at the end for me?

@author:
whoops good catch