title: TypeError: $ is not a function in selenium java during html5 dragdrop
body: <p><strong>Problem Statement:</strong> dragdrop function from selenium java class returns an exception <strong>org.openqa.selenium.JavascriptException: TypeError: $ is not a function</strong></p>
  
  <p>In few forums it was suggested to use js available in below location to perform html5 dragdrop in selenium java and followed same steps but resulted in above error. </p>
  
  <p>Selenium 3.141
  Chrome 76 </p>
  
  <p>drag_drop_function is defined in drag_drop_helper.js as below</p>
  
  <p>js reference: <a href="https://gist.github.com/rcorreia/2362544#file-drag_and_drop_helper-js" rel="nofollow noreferrer">https://gist.github.com/rcorreia/2362544#file-drag_and_drop_helper-js</a></p>
  
  <pre><code>(function($){
          $.fn.simulateDragDrop = function(options) {
                  return this.each(function() {
                          new $.simulateDragDrop(this, options);
                  });
          };
          $.simulateDragDrop = function(elem, options) {
                  this.options = options;
                  this.simulateEvent(elem, options);
          };
          $.extend($.simulateDragDrop.prototype, {
                  simulateEvent: function(elem, options) {
                          /*Simulating drag start*/
                          var type = 'dragstart';
                          var event = this.createEvent(type);
                          this.dispatchEvent(elem, type, event);
  
                          /*Simulating drop*/
                          type = 'drop';
                          var dropEvent = this.createEvent(type, {});
                          dropEvent.dataTransfer = event.dataTransfer;
                          this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);
  
                          /*Simulating drag end*/
                          type = 'dragend';
                          var dragEndEvent = this.createEvent(type, {});
                          dragEndEvent.dataTransfer = event.dataTransfer;
                          this.dispatchEvent(elem, type, dragEndEvent);
                  },
                  createEvent: function(type) {
                          var event = document.createEvent("CustomEvent");
                          event.initCustomEvent(type, true, true, null);
                          event.dataTransfer = {
                                  data: {
                                  },
                                  setData: function(type, val){
                                          this.data[type] = val;
                                  },
                                  getData: function(type){
                                          return this.data[type];
                                  }
                          };
                          return event;
                  },
                  dispatchEvent: function(elem, type, event) {
                          if(elem.dispatchEvent) {
                                  elem.dispatchEvent(event);
                          }else if( elem.fireEvent ) {
                                  elem.fireEvent("on"+type, event);
                          }
                  }
          });
  })(jQuery);
  </code></pre>
  
  <p>Below lines of code read js file and trigger html5 dragdrop function defined in js file</p>
  
  <pre><code> String js_filepath = "C:/test/drag_and_drop_helper.js";
             String java_script = "";
             String text;
             BufferedReader input = new BufferedReader(new FileReader(js_filepath));
             StringBuffer buffer = new StringBuffer();
             while ((text = input.readLine()) != null)
                  buffer.append(text + " ");
                  java_script = buffer.toString();
  
  WebElement source1 = driver.findElement(By.cssSelector("span.object-card-value[title=test]"));
  WebElement dest1 = driver.findElement(By.cssSelector("div[data-field-name='references']"));
  
   java_script = java_script + "$(arguments[0]).simulateDragDrop({dropTarget:arguments[1]});";
  ((JavascriptExecutor) driver).executeScript(java_script, source1, dest1);
  </code></pre>
  
  <p>Result:
  Elements are identified properly and js file is read as well but fails to trigger dragdrop with an error <strong>TypeError: $ is not a function</strong></p>
  
  <p><strong>Status 1:</strong></p>
  
  <p>@pcalkins Thank you. I tried as per your suggesstion but no drag drop action happens on both chrome and FF browsers. </p>
  
  <p>Only difference is I'm trying to pass using css selector as I dont have id. todrag and todrop elements are getting highlighted properly. No exceptions are thrown, but drag drop action doesn't happen.</p>
  
  <pre><code> var toDrag =document.querySelectorAll(\"span.object-card-value[title='test']\"); var toDrop = document.querySelectorAll(\" div[data-field-name='references']\");";
   ((JavascriptExecutor)driver).executeScript(simulateFunction + "simulateDragDrop(toDrag, toDrop);"); //also tried with queryselector
  </code></pre>
  
  <p><strong>Update2</strong> markup as below</p>
  
  <p>drag markup</p>
  
  <pre><code>&lt;ul class="object-list drop-target"&gt; changes to object-list drop-target active drag-over, drag-over triggers?
          &lt;li class="chooser add"&gt;&lt;div class="autocomplete"&gt;
          &lt;div class="autocomplete-searchbox" tabindex="1"&gt;
              &lt;input placeholder="Drop here " class="autocomplete-input autocomplete-single-select form-control" size="30" style="width: 100%;" type="text"&gt;
              &lt;span class="autocomplete-reset fonticon fonticon-clear"&gt;&lt;/span&gt;
          &lt;/div&gt;
          &lt;div class="autocomplete-suggests"&gt;
          &lt;div class="autocomplete-suggests-scroll  scroller scroller-root" style="overflow: hidden;"&gt;
          &lt;div class="no-native-scrollbars  scroller-content" style="right: -16px; bottom: -16px; padding-right: 16px; padding-bottom: 16px;"&gt;
          &lt;ul tabindex="1" class="scroller-shift"&gt;
              &lt;/ul&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
          &lt;button class="btn"&gt;&lt;span class="fonticon fonticon-search"&gt;&lt;/span&gt;&lt;/button&gt;&lt;/li&gt;
  
          &lt;li class="object-card has-image" data-field-name="item" data-type="Document" data-id="16C31E069B1C00009555C15DB7CC0B00" data-hasfiles="TRUE"&gt;
               &lt;span class="draggable-item" draggable="true"&gt;
                  &lt;span class="thumbnail object-image"&gt;
                     &lt;img draggable="false" oncontextmenu="return false" src="http://test.com" title="test"&gt;
                  &lt;/span&gt;
              &lt;span data-field-name="display-value"&gt;&lt;span class="object-card-value" oncontextmenu="return false" title="test" style="background: yellow; border: 2px solid red;"&gt;test&lt;/span&gt;&lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="actions"&gt;
                  &lt;button class="btn"&gt;
                      &lt;span class="fonticon fonticon-down-open" data-field-name="deliverables" title=""&gt;&lt;/span&gt;
                  &lt;/button&gt;
              &lt;/span&gt;
          &lt;/li&gt;
  
   WebElement source1 = driver.findElement(By.cssSelector("span.object-card-value[title='test']"));   
  </code></pre>
  
  <p>drop markup     </p>
  
  <pre><code>&lt;div id="card0"&gt;
  &lt;div class="card-content" data-id="16C31E069B1C00008B21C15D91F10B00" oncontextmenu="return false"&gt;
        &lt;div class="card-title"&gt;Context&lt;/div&gt;
        &lt;div class="card-properties"&gt;
              &lt;div class="card-details "&gt;
                    &lt;div class="thumbnail type"&gt;
                          &lt;span class="task"&gt;&lt;/span&gt;
   &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;    
  
   WebElement dest1 = driver.findElement(By.id("card0"));     
  </code></pre>
  
  <p>As soon as user moves drag element, a drag-over event seem to be triggered, which changes <strong>object-list drop-target</strong> to <code>object-list drop-target drag-over</code></p>