title: Fetching data to Django view working manually but not with Selenium. Why?
body: <p>I am using Selenium to test a Django app I have created. <br/>
  The following code works fine 'manually' but does not work with Selenium. <br/>
  Why ? <br/></p>
  <br/>
  ## dummy.html ##
  <br/>
  <pre class="lang-html prettyprint-override"><code>{% extends 'main.html' %}
  {% load static %}
  
  {% block title %}
  Dummy page
  {% endblock title %}
  
  {% block meta %}
  &lt;meta name=&quot;robots&quot; content=&quot;noindex&quot;&gt;
  {% endblock meta %}
  
  {% block content %}
  
  &lt;div class=&quot;container&quot;&gt;
      &lt;div class=&quot;row&quot;&gt;
          &lt;div class=&quot;col d-flex justify-content-center align-items-center&quot;&gt;
              &lt;h1 class=&quot;text-primary font-handwriting&quot;&gt;Dummy page&lt;/h1&gt;
          &lt;/div&gt;
      &lt;/div&gt;
      &lt;br&gt;
      &lt;div class=&quot;row&quot;&gt;
          &lt;div class=&quot;col d-flex justify-content-center align-items-center&quot;&gt;
              &lt;h2 class=&quot;text-primary font-heading&quot;&gt;THIS IS A DUMMY PAGE&lt;/h2&gt;
          &lt;/div&gt;
      &lt;/div&gt;
      &lt;br&gt;
      &lt;div class=&quot;row&quot;&gt;
          &lt;button id=&quot;trigger-dummy-button&quot; type=&quot;button&quot;
              class=&quot;btn btn-primary text-white font-base fw-bold text-uppercase&quot;
              title=&quot;Trigger dummy button&quot;&gt;Trigger dummy button&lt;/button&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;script&gt; 
      var someDummyURL = &quot;{% url 'home_page:another_dummy_view' %}&quot;;
  &lt;/script&gt;
  
  &lt;script type=&quot;module&quot; src=&quot;{% static '/js/dummy.js' %}&quot;&gt;  &lt;/script&gt;
  
  {% endblock content %}
  
  </code></pre>
  <br/>
  ## dummy.js ##
  <br/>
  <pre class="lang-js prettyprint-override"><code>'use strict';
  
  var newValue;
  
  async function postDummyFunction(request) {
      var response = await fetch(request);
      if (response.ok) {
          var updatedReturnedValue = await response.json();
          newValue = updatedReturnedValue.returnedValue;
          alert('-- postDummyFunction --  |  newValue = ' + newValue);
          // When the script is triggered manually by clicking, response.ok = true and newValue = &quot;Hello World OK !&quot;
          return newValue;
      } else {
          // When the script is triggered by Selenium, response.ok = false
          alert('-- postDummyFunction --  |  response.ok ? ' + response.ok);
          return false;
      }
  };
  
  
  document.addEventListener(&quot;DOMContentLoaded&quot;, function () {
  
      var triggerDummyButton = document.getElementById(&quot;trigger-dummy-button&quot;);
      var someDummyVariable = &quot;Hello World &quot;;
      var toPostURL = someDummyURL;
      
      triggerDummyButton.onclick = (e) =&gt; {
          var data = {&quot;dummyValue&quot;: someDummyVariable};
          var request = new Request(toPostURL, {
              method: &quot;POST&quot;,
              mode: &quot;same-origin&quot;,
              headers: {
                  &quot;Content-Type&quot;: &quot;application/json&quot;,
                  'X-Requested-With':'XMLHttpRequest',
                  &quot;Accept&quot;: &quot;application/json&quot;,
                  'X-CSRFToken': csrftoken
              },
              body: JSON.stringify(data),
          });
          // Works with Selenium
          // if alert(data.dummyValue), browser correctly displays &quot;Hello World &quot;
          postDummyFunction(request);
      }
  });
  
  </code></pre>
  <br/>
  ## views.py ##
  <br/>
  <pre class="lang-py prettyprint-override"><code>import json
  
  from django.shortcuts import render, redirect
  from django.http import JsonResponse
  
  
  def dev_dummy_script(request):
      context = {}
      return render(request, &quot;dummy.html&quot;, context)
  
  
  def another_dummy_view(request):
      if request.method == &quot;POST&quot;:
          post_data = json.loads(request.body.decode(&quot;utf-8&quot;))
          posted_value = post_data[&quot;dummyValue&quot;]
          value_to_return = posted_value + &quot; &quot; + &quot;OK !&quot;
          response = JsonResponse({&quot;returnedValue&quot;: value_to_return})
          return response
  
  </code></pre>
  <br/>
  ## test_selenium.py ##
  <br/>
  <pre class="lang-py prettyprint-override"><code>
  import time
  import os
  from decimal import Decimal
  from selenium import webdriver
  from selenium.webdriver.common.action_chains import ActionChains
  from selenium.webdriver.common.by import By
  from selenium.webdriver.common.keys import Keys
  from selenium.webdriver.support.ui import WebDriverWait
  from selenium.webdriver.support import expected_conditions as EC
  
  from django.contrib.staticfiles.testing import StaticLiveServerTestCase
  
  from core.settings import BASE_DIR
  
  PATH_TO_WEBDRIVER_CHROME = os.path.join(
      BASE_DIR, &quot;test&quot;, &quot;webdrivers&quot;, &quot;chromedriver.exe&quot;
  )
  
  PATH_TO_WEBDRIVER_FIREFOX = os.path.join(BASE_DIR, &quot;test&quot;, &quot;webdrivers&quot;, &quot;geckodriver&quot;)
  
  SHORT_TIME = 2.5
  LONG_TIME = 6
  DEFAULT_WAIT_TIME = 10
  
  
  class FooTest(StaticLiveServerTestCase):
      def setUp(self):
          self.browser = webdriver.Firefox(executable_path=PATH_TO_WEBDRIVER_FIREFOX)
  
      def tearDown(self):
          self.browser.close()
  
      def testfoo(self):
  
          self.browser.get((&quot;%s%s&quot; % (self.live_server_url, &quot;/dev/dummy_script/&quot;)))
  
          elem_trigger_btn = WebDriverWait(self.browser, DEFAULT_WAIT_TIME).until(
              EC.element_to_be_clickable((By.ID, &quot;trigger-dummy-button&quot;))
          )
  
          elem_trigger_btn.click()
  
          time.sleep(LONG_TIME)
  
          self.browser.close()
  
  </code></pre>
  <br/>
  <h2>versions</h2>
  <ul>
  <li>Django==3.2</li>
  <li>selenium==3.141.0</li>
  <li>Firefox 96.0.3</li>
  </ul>
  <br/>
  <p>If I trigger <code>python manage.py runserver</code>, manually head to <em>dummy_script</em> and click on the button, it works fine, i.e. alert window pops up and displays &quot;Hello World OK !&quot;.<br/>
  <br/>
  If I trigger the script with pytest and selenium, the code is executed, but response returned from fetch is ko. <br/></p>
  <h2>EDIT</h2>
  <h2>main.html</h2>
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  {% load static %}
  &lt;html lang=&quot;fr&quot;&gt;
  
  &lt;head&gt;
  
      &lt;meta charset=&quot;utf-8&quot;&gt;
      &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  
      &lt;link href=&quot;{% static 'css/main.css' %}&quot; rel=&quot;stylesheet&quot;&gt;
  
      &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css&quot;&gt;
  
      &lt;script src=&quot;{% static 'js/bootstrap.js' %}&quot;&gt;&lt;/script&gt;
  
      &lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js&quot;
          integrity=&quot;sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4&quot;
          crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  
      &lt;script type=&quot;text/javascript&quot;&gt;
  
          function getCookie(name) {
              let cookieValue = null;
              if (document.cookie &amp;&amp; document.cookie !== '') {
                  const cookies = document.cookie.split(';');
                  for (let i = 0; i &lt; cookies.length; i++) {
                      const cookie = cookies[i].trim();
                      // Does this cookie string begin with the name we want?
                      if (cookie.substring(0, name.length + 1) === (name + '=')) {
                          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                          break;
                      }
                  }
              }
              return cookieValue;
          }
          const csrftoken = getCookie('csrftoken');
  
      &lt;/script&gt;
  
      &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot;
          integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  
      &lt;title&gt;
          {% block title %}
          {% endblock title %}
      &lt;/title&gt;
      {% block meta %}
      {% endblock meta %}
  
  &lt;/head&gt;
  
  &lt;body class=&quot;mt-sm-5 mt-md-5 mt-lg-5 mt-xl-5&quot;&gt;
      &lt;section class=&quot;page-content py-3&quot; id=&quot;page-content&quot;&gt;
          {% block content %}
          {% endblock content %}
      &lt;/section&gt;
  
      &lt;script type=&quot;module&quot; src=&quot;{% static '/js/main.js' %}&quot;&gt;  &lt;/script&gt;
  
  &lt;/body&gt;
  
  &lt;/html&gt;
  
  </code></pre>