Adam Shaw 6 лет назад
Родитель
Сommit
90d3f0d25e
35 измененных файлов с 714 добавлено и 741 удалено
  1. 1 1
      packages-premium
  2. 4 6
      packages/__tests__/src/event-drag/between-calendars.js
  3. 14 8
      packages/__tests__/src/event-render/minSegmentHeight.js
  4. 6 3
      packages/__tests__/src/event-render/print-preview.js
  5. 4 2
      packages/__tests__/src/event-source/navigation.js
  6. 18 17
      packages/__tests__/src/event-source/remove.js
  7. 3 18
      packages/__tests__/src/legacy/aspectRatio.js
  8. 39 26
      packages/__tests__/src/legacy/background-events.js
  9. 103 98
      packages/__tests__/src/legacy/current-date.js
  10. 0 20
      packages/__tests__/src/legacy/daygrid-view.js
  11. 11 9
      packages/__tests__/src/legacy/event-coloring.js
  12. 36 132
      packages/__tests__/src/legacy/firstDay.js
  13. 83 75
      packages/__tests__/src/legacy/header-rendering.js
  14. 18 12
      packages/__tests__/src/legacy/locale.js
  15. 16 10
      packages/__tests__/src/legacy/nextDayThreshold.js
  16. 41 62
      packages/__tests__/src/legacy/nowIndicator.js
  17. 16 11
      packages/__tests__/src/legacy/removeEventSources.js
  18. 26 34
      packages/__tests__/src/legacy/scroll-state.js
  19. 9 4
      packages/__tests__/src/legacy/selectMirror.js
  20. 26 14
      packages/__tests__/src/legacy/slotDuration.js
  21. 48 48
      packages/__tests__/src/legacy/weekNumberCalculation.js
  22. 29 56
      packages/__tests__/src/legacy/weekNumbers.js
  23. 9 17
      packages/__tests__/src/legacy/weekViewRender.js
  24. 12 8
      packages/__tests__/src/lib/dnd-resize-utils.js
  25. 0 5
      packages/__tests__/src/lib/dom-misc.js
  26. 6 1
      packages/__tests__/src/lib/wrappers/CalendarWrapper.ts
  27. 25 0
      packages/__tests__/src/lib/wrappers/DayGridWrapper.ts
  28. 9 0
      packages/__tests__/src/lib/wrappers/DayHeaderWrapper.ts
  29. 20 5
      packages/__tests__/src/lib/wrappers/TimeGridWrapper.ts
  30. 33 1
      packages/__tests__/src/lib/wrappers/ToolbarWrapper.ts
  31. 15 8
      packages/__tests__/src/theme/bootstrap4.js
  32. 12 11
      packages/__tests__/src/theme/switching.js
  33. 7 8
      packages/__tests__/src/view-render/rerender.js
  34. 9 6
      packages/__tests__/src/view-render/scrollToTime.js
  35. 6 5
      packages/__tests__/src/view-render/updateSize.js

+ 1 - 1
packages-premium

@@ -1 +1 @@
-Subproject commit fecf126f98e70a00aec127d0c2f46ed9ef58a507
+Subproject commit a234d54d2193c62057eab3bcce2117882d51f70b

+ 4 - 6
packages/__tests__/src/event-drag/between-calendars.js

@@ -5,6 +5,7 @@ import TimeGridPlugin from '@fullcalendar/timegrid'
 import { getRectCenter } from '../lib/geom'
 import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
 import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
+import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
 
 
 describe('dragging events between calendars', function() {
@@ -89,11 +90,9 @@ describe('dragging events between calendars', function() {
 
     let eventEl = dayGridWrapper0.getEventEls()[0]
     let dayEl = dayGridWrapper1.getDayEls('2019-01-05')[0]
-    let point0 = getRectCenter(eventEl.getBoundingClientRect())
     let point1 = getRectCenter(dayEl.getBoundingClientRect())
 
     $(eventEl).simulate('drag', {
-      point: point0,
       end: point1,
       callback: function() {
         expect(triggerNames).toEqual([ 'eventLeave', 'drop', 'eventReceive' ])
@@ -133,12 +132,11 @@ describe('dragging events between calendars', function() {
     calendar0.render()
     calendar1.render()
 
-    let eventEl = new CalendarWrapper(calendar0).getEventEls()[0]
-    let point0 = getRectCenter(eventEl.getBoundingClientRect())
-    let point1 = getRectCenter(el1.querySelector('.scrollgrid .fc-body:last-child .fc-scroller').getBoundingClientRect())
+    let eventEl = new CalendarWrapper(calendar0).getEventEls()[0] // of the source calendar
+    let destViewWrapper = new TimeGridViewWrapper(calendar1)
+    let point1 = getRectCenter(destViewWrapper.getScrollerEl().getBoundingClientRect())
 
     $(eventEl).simulate('drag', {
-      point: point0,
       end: point1
     })
   })

+ 14 - 8
packages/__tests__/src/event-render/minSegmentHeight.js

@@ -1,4 +1,6 @@
 import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
+import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
+import { queryEventElInfo } from '../lib/wrappers/TimeGridWrapper'
 
 describe('short event rendering with timeGridEventMinHeight', function() {
   pushOptions({
@@ -31,22 +33,26 @@ describe('short event rendering with timeGridEventMinHeight', function() {
     })
 
     it('renders the second short event side by side with the first one', function() {
-      initCalendar()
-      var el2 = $('.fc-short').eq(1)
+      let calendar = initCalendar()
+      let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+      let eventEls = timeGridWrapper.getEventEls()
 
-      expect(el2.css('left')).not.toEqual('0px')
+      expect(queryEventElInfo(eventEls[1]).isShort).toBe(true)
+      expect($(eventEls[1]).css('left')).not.toEqual('0px')
     })
 
     it('prevents the events to overlap when we pass the slotEventOverlap: false option', function() {
-      initCalendar({
+      let calendar = initCalendar({
         slotEventOverlap: false
       })
+      let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+      let eventEls = timeGridWrapper.getEventEls()
 
-      var el1 = $('.fc-short').eq(0)
-      var el2 = $('.fc-short').eq(1)
+      expect(queryEventElInfo(eventEls[0]).isShort).toBe(true)
+      expect(queryEventElInfo(eventEls[1]).isShort).toBe(true)
 
-      expect(el1.css('left')).toEqual('0px')
-      expect(el2.css('left')).not.toEqual('0px')
+      expect($(eventEls[0]).css('left')).toEqual('0px')
+      expect($(eventEls[1]).css('left')).not.toEqual('0px')
     })
   })
 })

+ 6 - 3
packages/__tests__/src/event-render/print-preview.js

@@ -1,3 +1,4 @@
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
 
 describe('print preview', function() {
   pushOptions({
@@ -18,11 +19,13 @@ describe('print preview', function() {
   }, function() {
 
     it('orders events in DOM by start time', function() {
-      initCalendar()
+      let calendar = initCalendar()
+      let calendarWrapper = new CalendarWrapper(calendar)
+      let eventEls = calendarWrapper.getEventEls()
 
-      let ids = $('.fc-event').map(function(i, el) {
+      let ids = eventEls.map(function(el) {
         return el.getAttribute('data-id')
-      }).get()
+      })
 
       expect(ids).toEqual([ '1', '2' ])
     })

+ 4 - 2
packages/__tests__/src/event-source/navigation.js

@@ -1,10 +1,11 @@
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
 
 describe('event fetching while date-navigating', function() {
 
   // https://github.com/fullcalendar/fullcalendar/issues/4975
   it('renders events when doing next() and then prev()', function(done) {
 
-    initCalendar({
+    let calendar = initCalendar({
       defaultView: 'dayGridMonth',
       defaultDate: '2020-02-11',
       events: function(arg, callback) {
@@ -25,6 +26,7 @@ describe('event fetching while date-navigating', function() {
         }
       }
     })
+    let calendarWrapper = new CalendarWrapper(calendar)
 
     setTimeout(function() {
 
@@ -34,7 +36,7 @@ describe('event fetching while date-navigating', function() {
         currentCalendar.prev()
         setTimeout(function() {
 
-          expect($('.fc-event').length).toBe(1)
+          expect(calendarWrapper.getEventEls().length).toBe(1)
           done()
 
         }, 1000) // after everything

+ 18 - 17
packages/__tests__/src/event-source/remove.js

@@ -1,10 +1,12 @@
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
+
 describe('event source remove', function() {
   pushOptions({
     defaultDate: '2014-08-01'
   })
 
   it('correctly removes events provided via `eventSources` at initialization', function() {
-    initCalendar({
+    let calendar = initCalendar({
       eventSources: [ {
         id: '5',
         events: [
@@ -13,15 +15,19 @@ describe('event source remove', function() {
         ]
       } ]
     })
+    let calendarWrapper = new CalendarWrapper(calendar)
+
+    expect(calendar.getEvents().length).toBe(2)
+    expect(calendarWrapper.getEventEls().length).toBe(2)
+
+    calendar.getEventSourceById('5').remove()
 
-    expectEventCnt(2)
-    currentCalendar.getEventSourceById('5').remove()
-    expectEventCnt(0)
+    expect(calendar.getEvents().length).toBe(0)
+    expect(calendarWrapper.getEventEls().length).toBe(0)
   })
 
   it('won\'t render removed events when subsequent addEventSource', function(done) {
-
-    var source1 = {
+    let source1 = {
       id: '1',
       events: function(arg, callback) {
         setTimeout(function() {
@@ -34,7 +40,7 @@ describe('event source remove', function() {
       }
     }
 
-    var source2 = {
+    let source2 = {
       id: '2',
       events: function(arg, callback) {
         setTimeout(function() {
@@ -47,10 +53,11 @@ describe('event source remove', function() {
       }
     }
 
-    initCalendar({
+    let calendar = initCalendar({
       eventSources: [ source1 ],
       _eventsPositioned() {
-        if (!$('.fc-event').length) {
+        let eventEls = new CalendarWrapper(this).getEventEls()
+        if (!eventEls.length) {
           ; // might have rendered no events after removeEventSource call
         } else {
           expect($('.event1').length).toBe(0)
@@ -60,13 +67,7 @@ describe('event source remove', function() {
       }
     })
 
-    currentCalendar.getEventSourceById('1').remove()
-    currentCalendar.addEventSource(source2)
+    calendar.getEventSourceById('1').remove()
+    calendar.addEventSource(source2)
   })
-
-  function expectEventCnt(cnt) {
-    expect($('.fc-event').length).toBe(cnt)
-    expect(currentCalendar.getEvents().length).toBe(cnt)
-  }
-
 })

+ 3 - 18
packages/__tests__/src/legacy/aspectRatio.js

@@ -8,7 +8,7 @@ describe('aspectRatio', function() {
 
   describe('when default settings are used', function() {
 
-    var elementWidth = 675
+    const elementWidth = 675
 
     it('view div should use the ratio 1:35 to set height', function() {
       let calendar = initCalendar({}, getCalendarElement(elementWidth))
@@ -25,15 +25,13 @@ describe('aspectRatio', function() {
       var rect = viewContainerEl.getBoundingClientRect()
       expect(Math.round(rect.width)).toEqual(elementWidth)
     })
-
   })
 
   describe('when initializing the aspectRatio', function() {
 
-    var elementWidth = 1000
+    const elementWidth = 1000
 
     describe('to 2', function() {
-
       pushOptions({
         aspectRatio: 2
       })
@@ -54,11 +52,9 @@ describe('aspectRatio', function() {
         var ratio = Math.round(rect.width / rect.height * 100)
         expect(Math.round(ratio)).toEqual(200)
       })
-
     })
 
     describe('to 1', function() {
-
       pushOptions({
         aspectRatio: 1
       })
@@ -79,11 +75,9 @@ describe('aspectRatio', function() {
         var ratio = Math.round(rect.width / rect.height * 100)
         expect(Math.round(ratio)).toEqual(100)
       })
-
     })
 
     describe('to less than 0.5', function() {
-
       pushOptions({
         aspectRatio: 0.4
       })
@@ -108,7 +102,6 @@ describe('aspectRatio', function() {
     })
 
     describe('to negative', function() {
-
       pushOptions({
         aspectRatio: -2
       })
@@ -129,11 +122,9 @@ describe('aspectRatio', function() {
         var ratio = Math.round(rect.width / rect.height * 100)
         expect(Math.round(ratio)).toEqual(50)
       })
-
     })
 
     describe('to zero', function() {
-
       pushOptions({
         aspectRatio: 0
       })
@@ -154,11 +145,9 @@ describe('aspectRatio', function() {
         var ratio = Math.round(rect.width / rect.height * 100)
         expect(Math.round(ratio)).toEqual(50)
       })
-
     })
 
     describe('to very large', function() {
-
       pushOptions({
         aspectRatio: 4000
       })
@@ -175,14 +164,10 @@ describe('aspectRatio', function() {
         let calendar = initCalendar({}, getCalendarElement(elementWidth))
         let viewContainerEl = new CalendarWrapper(calendar).getViewContainerEl()
 
-        var actualHeight = viewContainerEl.getBoundingClientRect().height
-        $('tr.fc-week td:first-child > div').css('min-height', '').css('background', 'red')
+        let actualHeight = viewContainerEl.getBoundingClientRect().height
         var naturalHeight = viewContainerEl.getBoundingClientRect().height
         expect(Math.round(actualHeight)).toEqual(Math.round(naturalHeight))
       })
-
     })
-
   })
-
 })

+ 39 - 26
packages/__tests__/src/legacy/background-events.js

@@ -2,9 +2,9 @@ import { RED_REGEX } from '../lib/dom-misc'
 import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
 import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
 
-describe('background events', function() {
+// SEE ALSO: event-color.js
 
-  // SEE ALSO: event-color.js
+describe('background events', function() {
   pushOptions({
     defaultDate: '2014-11-04',
     scrollTime: '00:00'
@@ -29,7 +29,7 @@ describe('background events', function() {
 
         expect(allBgEls.length).toBe(1)
         expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
-        expect(allBgEls[0]).toBeLeftOf('.fc-day[data-date="2014-11-05"]')
+        expect(allBgEls[0]).toBeLeftOf(dayGridWrapper.getDayEl('2014-11-05'))
         expect(dayGridWrapper.getEventEls().length).toBe(0)
       })
 
@@ -49,8 +49,8 @@ describe('background events', function() {
         expect(allBgEls.length).toBe(2)
         expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
         expect(dayGridWrapper.getBgEventEls(2).length).toBe(1)
-        expect(allBgEls[0]).toBeRightOf('.fc-day[data-date="2014-11-03"]')
-        expect(allBgEls[1]).toBeLeftOf('.fc-day[data-date="2014-11-12"]')
+        expect(allBgEls[0]).toBeRightOf(dayGridWrapper.getDayEl('2014-11-03'))
+        expect(allBgEls[1]).toBeLeftOf(dayGridWrapper.getDayEl('2014-11-12'))
         expect(dayGridWrapper.getEventEls().length).toBe(0)
       })
 
@@ -75,8 +75,8 @@ describe('background events', function() {
 
         expect(allBgEls.length).toBe(2)
         expect(dayGridWrapper.getBgEventEls(1).length).toBe(2)
-        expect(allBgEls[0]).toBeRightOf('.fc-day[data-date="2014-11-02"]')
-        expect(allBgEls[1]).toBeLeftOf('.fc-day[data-date="2014-11-08"]')
+        expect(allBgEls[0]).toBeRightOf(dayGridWrapper.getDayEl('2014-11-02'))
+        expect(allBgEls[1]).toBeLeftOf(dayGridWrapper.getDayEl('2014-11-08'))
         expect(dayGridWrapper.getEventEls().length).toBe(0)
       })
 
@@ -97,7 +97,7 @@ describe('background events', function() {
 
           expect(allBgEls.length).toBe(1)
           expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
-          expect(allBgEls).toBeRightOf('.fc-day-grid .fc-row:eq(1) .fc-week-number')
+          expect(allBgEls).toBeRightOf(dayGridWrapper.getWeekCell(1))
           expect(dayGridWrapper.getEventEls().length).toBe(0)
         })
       })
@@ -128,7 +128,7 @@ describe('background events', function() {
 
         expect(allBgEls.length).toBe(1)
         expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
-        expect(allBgEls[0]).toBeRightOf('.fc-day[data-date="2014-11-06"]')
+        expect(allBgEls[0]).toBeRightOf(dayGridWrapper.getDayEl('2014-11-06'))
         expect(dayGridWrapper.getEventEls().length).toBe(0)
       })
 
@@ -148,8 +148,8 @@ describe('background events', function() {
         expect(allBgEls.length).toBe(2)
         expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
         expect(dayGridWrapper.getBgEventEls(2).length).toBe(1)
-        expect(allBgEls[0]).toBeLeftOf('.fc-day[data-date="2014-11-02"]')
-        expect(allBgEls[1]).toBeRightOf('.fc-day[data-date="2014-11-12"]')
+        expect(allBgEls[0]).toBeLeftOf(dayGridWrapper.getDayEl('2014-11-02'))
+        expect(allBgEls[1]).toBeRightOf(dayGridWrapper.getDayEl('2014-11-12'))
         expect(dayGridWrapper.getEventEls().length).toBe(0)
       })
 
@@ -169,7 +169,7 @@ describe('background events', function() {
 
           expect(allBgEls.length).toBe(1)
           expect(dayGridWrapper.getBgEventEls(1).length).toBe(1)
-          expect(allBgEls[0]).toBeLeftOf('.fc-day-grid .fc-row:eq(1) .fc-week-number span')
+          expect(allBgEls[0]).toBeLeftOf(dayGridWrapper.getWeekCell(1))
           expect(dayGridWrapper.getEventEls().length).toBe(0)
         })
       })
@@ -200,10 +200,10 @@ describe('background events', function() {
           let secondRowBgEls = dayGridWrapper.getBgEventEls(1)
 
           expect(secondRowBgEls[0])
-            .toBeLeftOf('.fc-day[data-date="2014-11-05"]')
+            .toBeLeftOf(dayGridWrapper.getDayEl('2014-11-05'))
 
           expect(secondRowBgEls[1])
-            .toBeRightOf('.fc-day[data-date="2014-11-03"]')
+            .toBeRightOf(dayGridWrapper.getDayEl('2014-11-03'))
 
           expect(dayGridWrapper.getEventEls().length).toBe(0)
         })
@@ -228,10 +228,10 @@ describe('background events', function() {
           expect(dayGridWrapper.getBgEventEls(5).length).toBe(1)
 
           expect(dayGridWrapper.getBgEventEls(1)[0])
-            .toBeLeftOf('.fc-day[data-date="2014-11-05"]')
+            .toBeLeftOf(dayGridWrapper.getDayEl('2014-11-05'))
 
           expect(dayGridWrapper.getBgEventEls(2)[0])
-            .toBeRightOf('.fc-day[data-date="2014-11-09"]')
+            .toBeRightOf(dayGridWrapper.getDayEl('2014-11-09'))
 
           expect(dayGridWrapper.getEventEls().length).toBe(0)
         })
@@ -255,7 +255,7 @@ describe('background events', function() {
           expect(dayGridWrapper.getBgEventEls(5).length).toBe(1)
 
           expect(dayGridWrapper.getBgEventEls(1))
-            .toBeRightOf('.fc-day[data-date="2014-11-04"]')
+            .toBeRightOf(dayGridWrapper.getDayEl('2014-11-04'))
         })
 
         it('render correctly when ends after end of month', function() {
@@ -278,7 +278,7 @@ describe('background events', function() {
           expect(dayGridWrapper.getBgEventEls(5).length).toBe(0)
 
           expect(dayGridWrapper.getBgEventEls(4))
-            .toBeLeftOf('.fc-day[data-date="2014-11-28"]')
+            .toBeLeftOf(dayGridWrapper.getDayEl('2014-11-28'))
         })
 
         it('render correctly with two related events, in reverse order', function() {
@@ -390,10 +390,15 @@ describe('background events', function() {
         let allBgEvents = timeGridWrapper.getBgEventEls()
 
         expect(allBgEvents.length).toBe(1)
-        expect(timeGridWrapper.queryBgEventsInCol(2).length).toBe(1) // column 2
-        expect(allBgEvents[0]).toBeBelow('.fc-slats tr:eq(0)') // should be 1am (eq(1)) but FF cmplaning
-        expect(allBgEvents[0]).toBeAbove('.fc-slats tr:eq(10)') // 5am
-        expect(timeGridWrapper.getEventEls().length).toBe(0)
+        expect(timeGridWrapper.queryBgEventsInCol(2).length).toBe(1) // column
+        expect(timeGridWrapper.getEventEls().length).toBe(0) // no fg events
+
+        let rect = allBgEvents[0].getBoundingClientRect()
+        let topDiff = Math.abs(rect.top - timeGridWrapper.getTimeTop('01:00:00')) // TODO: make more exact
+        let bottomDiff = Math.abs(rect.bottom - timeGridWrapper.getTimeTop('05:00:00'))
+
+        expect(topDiff).toBeLessThanOrEqual(1)
+        expect(bottomDiff).toBeLessThanOrEqual(1)
       })
 
       it('render correctly spanning multiple days', function() {
@@ -491,8 +496,13 @@ describe('background events', function() {
 
         expect(allBgEls.length).toBe(1)
         expect(timeGridWrapper.queryBgEventsInCol(2).length).toBe(1)
-        expect(allBgEls[0]).toBeBelow('.fc-slats tr:eq(0)') // should be 1am (eq(1)) but FF cmplaining
-        expect(allBgEls[0]).toBeAbove('.fc-slats tr:eq(10)') // 5am
+
+        let rect = allBgEls[0].getBoundingClientRect()
+        let topDiff = Math.abs(rect.top - timeGridWrapper.getTimeTop('01:00:00'))
+        let bottomDiff = Math.abs(rect.bottom - timeGridWrapper.getTimeTop('05:00:00'))
+
+        expect(topDiff).toBeLessThanOrEqual(1) // TODO: tighten up
+        expect(bottomDiff).toBeLessThanOrEqual(1)
       })
 
       it('render correctly spanning multiple days', function() {
@@ -682,8 +692,11 @@ describe('background events', function() {
           expect(timeGridWrapper.queryBgEventsInCol(4).length).toBe(1)
           expect(timeGridWrapper.queryBgEventsInCol(5).length).toBe(1)
           expect(timeGridWrapper.queryBgEventsInCol(6).length).toBe(1)
-          expect(allBgEls[3]).toBeAbove('.fc-slats tr:eq(2)') // first part before 1am
-          expect(allBgEls[4]).toBeBelow('.fc-slats tr:eq(9)') // second part after 5am
+
+          expect(allBgEls[3].getBoundingClientRect().top)
+            .toBeLessThan(timeGridWrapper.getTimeTop('01:00:00'))
+          expect(allBgEls[4].getBoundingClientRect().bottom)
+            .toBeGreaterThan(timeGridWrapper.getTimeTop('05:00:00'))
         })
 
       })

+ 103 - 98
packages/__tests__/src/legacy/current-date.js

@@ -1,8 +1,9 @@
 import { addDays } from '@fullcalendar/core'
 import { parseUtcDate } from '../lib/date-parsing'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
 
 describe('current date', function() {
-  var TITLE_FORMAT = {
+  const TITLE_FORMAT = {
     month: 'long',
     day: 'numeric',
     year: 'numeric',
@@ -20,38 +21,38 @@ describe('current date', function() {
   describe('defaultDate & getDate', function() { // keep getDate
     describeWhenInMonth(function() {
       it('should initialize at the date', function() {
-        var options = {}
-        options.defaultDate = '2011-03-10'
-        initCalendar(options)
-        expectViewDates('2011-02-27', '2011-04-10', '2011-03-01', '2011-04-01')
-        var currentDate = currentCalendar.getDate()
+        let calendar = initCalendar({
+          defaultDate: '2011-03-10'
+        })
+        expectViewDates(calendar, '2011-02-27', '2011-04-10', '2011-03-01', '2011-04-01')
+        let currentDate = calendar.getDate()
         expect(currentDate instanceof Date).toEqual(true) // test the type, but only here
         expect(currentDate).toEqualDate('2011-03-10')
       })
     })
     describeWhenInWeek(function() {
       it('should initialize at the date, given a date string', function() {
-        var options = {}
-        options.defaultDate = '2011-03-10'
-        initCalendar(options)
-        expectViewDates('2011-03-06', '2011-03-13')
-        expect(currentCalendar.getDate()).toEqualDate('2011-03-10')
+        let calendar = initCalendar({
+          defaultDate: '2011-03-10'
+        })
+        expectViewDates(calendar, '2011-03-06', '2011-03-13')
+        expect(calendar.getDate()).toEqualDate('2011-03-10')
       })
       it('should initialize at the date, given a Date object', function() {
-        var options = {}
-        options.defaultDate = parseUtcDate('2011-03-10')
-        initCalendar(options)
-        expectViewDates('2011-03-06', '2011-03-13')
-        expect(currentCalendar.getDate()).toEqualDate('2011-03-10')
+        let calendar = initCalendar({
+          defaultDate: parseUtcDate('2011-03-10')
+        })
+        expectViewDates(calendar, '2011-03-06', '2011-03-13')
+        expect(calendar.getDate()).toEqualDate('2011-03-10')
       })
     })
     describeWhenInDay(function() {
       it('should initialize at the date', function() {
-        var options = {}
-        options.defaultDate = '2011-03-10'
-        initCalendar(options)
-        expectViewDates('2011-03-10')
-        expect(currentCalendar.getDate()).toEqualDate('2011-03-10')
+        let calendar = initCalendar({
+          defaultDate: '2011-03-10'
+        })
+        expectViewDates(calendar, '2011-03-10')
+        expect(calendar.getDate()).toEqualDate('2011-03-10')
       })
     })
   })
@@ -59,33 +60,33 @@ describe('current date', function() {
   describe('gotoDate', function() {
     describeWhenInMonth(function() {
       it('should go to a date when given a date string', function() {
-        initCalendar()
-        currentCalendar.gotoDate('2015-04-01')
-        expectViewDates('2015-03-29', '2015-05-10', '2015-04-01', '2015-05-01')
+        let calendar = initCalendar()
+        calendar.gotoDate('2015-04-01')
+        expectViewDates(calendar, '2015-03-29', '2015-05-10', '2015-04-01', '2015-05-01')
       })
     })
     describeWhenInWeek(function() {
       it('should go to a date when given a date string', function() {
-        initCalendar()
-        currentCalendar.gotoDate('2015-04-01')
-        expectViewDates('2015-03-29', '2015-04-05')
+        let calendar = initCalendar()
+        calendar.gotoDate('2015-04-01')
+        expectViewDates(calendar, '2015-03-29', '2015-04-05')
       })
       it('should go to a date when given a date string with a time', function() {
-        initCalendar()
-        currentCalendar.gotoDate('2015-04-01T12:00:00')
-        expectViewDates('2015-03-29', '2015-04-05')
+        let calendar = initCalendar()
+        calendar.gotoDate('2015-04-01T12:00:00')
+        expectViewDates(calendar, '2015-03-29', '2015-04-05')
       })
       it('should go to a date when given a Date object', function() {
-        initCalendar()
-        currentCalendar.gotoDate(parseUtcDate('2015-04-01'))
-        expectViewDates('2015-03-29', '2015-04-05')
+        let calendar = initCalendar()
+        calendar.gotoDate(parseUtcDate('2015-04-01'))
+        expectViewDates(calendar, '2015-03-29', '2015-04-05')
       })
     })
     describeWhenInDay(function() {
       it('should go to a date when given a date string', function() {
-        initCalendar()
-        currentCalendar.gotoDate('2015-04-01')
-        expectViewDates('2015-04-01')
+        let calendar = initCalendar()
+        calendar.gotoDate('2015-04-01')
+        expectViewDates(calendar, '2015-04-01')
       })
     })
   })
@@ -93,33 +94,33 @@ describe('current date', function() {
   describe('incrementDate', function() {
     describeWhenInMonth(function() {
       it('should increment the date when given a Duration object', function() {
-        initCalendar()
-        currentCalendar.incrementDate({ months: -1 })
-        expectViewDates('2014-04-27', '2014-06-08', '2014-05-01', '2014-06-01')
+        let calendar = initCalendar()
+        calendar.incrementDate({ months: -1 })
+        expectViewDates(calendar, '2014-04-27', '2014-06-08', '2014-05-01', '2014-06-01')
       })
     })
     describeWhenInWeek(function() {
       it('should increment the date when given a Duration object', function() {
-        initCalendar()
-        currentCalendar.incrementDate({ weeks: -2 })
-        expectViewDates('2014-05-18', '2014-05-25')
+        let calendar = initCalendar()
+        calendar.incrementDate({ weeks: -2 })
+        expectViewDates(calendar, '2014-05-18', '2014-05-25')
       })
     })
     describeWhenInDay(function() {
       it('should increment the date when given a Duration object', function() {
-        initCalendar()
-        currentCalendar.incrementDate({ days: 2 })
-        expectViewDates('2014-06-03')
+        let calendar = initCalendar()
+        calendar.incrementDate({ days: 2 })
+        expectViewDates(calendar, '2014-06-03')
       })
       it('should increment the date when given a Duration string', function() {
-        initCalendar()
-        currentCalendar.incrementDate('2.00:00:00')
-        expectViewDates('2014-06-03')
+        let calendar = initCalendar()
+        calendar.incrementDate('2.00:00:00')
+        expectViewDates(calendar, '2014-06-03')
       })
       it('should increment the date when given a Duration string with a time', function() {
-        initCalendar()
-        currentCalendar.incrementDate('2.05:30:00')
-        expectViewDates('2014-06-03')
+        let calendar = initCalendar()
+        calendar.incrementDate('2.05:30:00')
+        expectViewDates(calendar, '2014-06-03')
       })
     })
   })
@@ -127,23 +128,23 @@ describe('current date', function() {
   describe('prevYear', function() {
     describeWhenInMonth(function() {
       it('should move the calendar back a year', function() {
-        initCalendar()
-        currentCalendar.prevYear()
-        expectViewDates('2013-05-26', '2013-07-07', '2013-06-01', '2013-07-01')
+        let calendar = initCalendar()
+        calendar.prevYear()
+        expectViewDates(calendar, '2013-05-26', '2013-07-07', '2013-06-01', '2013-07-01')
       })
     })
     describeWhenInWeek(function() {
       it('should move the calendar back a year', function() {
-        initCalendar()
-        currentCalendar.prevYear()
-        expectViewDates('2013-05-26', '2013-06-02')
+        let calendar = initCalendar()
+        calendar.prevYear()
+        expectViewDates(calendar, '2013-05-26', '2013-06-02')
       })
     })
     describeWhenInDay(function() {
       it('should move the calendar back a year', function() {
-        initCalendar()
-        currentCalendar.prevYear()
-        expectViewDates('2013-06-01')
+        let calendar = initCalendar()
+        calendar.prevYear()
+        expectViewDates(calendar, '2013-06-01')
       })
     })
   })
@@ -151,23 +152,23 @@ describe('current date', function() {
   describe('nextYear', function() {
     describeWhenInMonth(function() {
       it('should move the calendar forward a year', function() {
-        initCalendar()
-        currentCalendar.nextYear()
-        expectViewDates('2015-05-31', '2015-07-12', '2015-06-01', '2015-07-01')
+        let calendar = initCalendar()
+        calendar.nextYear()
+        expectViewDates(calendar, '2015-05-31', '2015-07-12', '2015-06-01', '2015-07-01')
       })
     })
     describeWhenInWeek(function() {
       it('should move the calendar forward a year', function() {
-        initCalendar()
-        currentCalendar.nextYear()
-        expectViewDates('2015-05-31', '2015-06-07')
+        let calendar = initCalendar()
+        calendar.nextYear()
+        expectViewDates(calendar, '2015-05-31', '2015-06-07')
       })
     })
     describeWhenInDay(function() {
       it('should move the calendar forward a year', function() {
-        initCalendar()
-        currentCalendar.nextYear()
-        expectViewDates('2015-06-01')
+        let calendar = initCalendar()
+        calendar.nextYear()
+        expectViewDates(calendar, '2015-06-01')
       })
     })
   })
@@ -175,22 +176,24 @@ describe('current date', function() {
   describe('when current date is a hidden day', function() {
     describeWhenInMonth(function() {
       it('should display the current month even if first day of month', function() {
-        var options = {}
-        options.now = options.defaultDate = '2014-06-01' // a Sunday
-        options.weekends = false
-        initCalendar(options)
-        var view = currentCalendar.view
+        let calendar = initCalendar({
+          now: '2014-06-01', // a Sunday
+          defaultDate: '2014-06-01', // a Sunday
+          weekends: false
+        })
+        let view = calendar.view
         expect(view.activeStart).toEqualDate('2014-06-02')
         expect(view.activeEnd).toEqualDate('2014-07-12')
         expect(view.currentStart).toEqualDate('2014-06-01')
         expect(view.currentEnd).toEqualDate('2014-07-01')
       })
       it('should display the current month', function() {
-        var options = {}
-        options.now = options.defaultDate = '2014-05-04' // a Sunday
-        options.weekends = false
-        initCalendar(options)
-        var view = currentCalendar.view
+        let calendar = initCalendar({
+          now: '2014-05-04', // a Sunday
+          defaultDate: '2014-05-04', // a Sunday
+          weekends: false
+        })
+        let view = calendar.view
         expect(view.activeStart).toEqualDate('2014-04-28')
         expect(view.activeEnd).toEqualDate('2014-06-07')
         expect(view.currentStart).toEqualDate('2014-05-01')
@@ -198,15 +201,15 @@ describe('current date', function() {
       })
       describe('when navigating back a month', function() {
         it('should not skip months', function() {
-          var options = {}
-          options.defaultDate = '2014-07-07'
-          options.weekends = false
-          initCalendar(options)
-          var view = currentCalendar.view
+          let calendar = initCalendar({
+            defaultDate: '2014-07-07',
+            weekends: false
+          })
+          let view = calendar.view
           expect(view.currentStart).toEqualDate('2014-07-01')
           expect(view.currentEnd).toEqualDate('2014-08-01')
-          currentCalendar.prev() // will move to Jun 1, which is a Sunday
-          view = currentCalendar.view
+          calendar.prev() // will move to Jun 1, which is a Sunday
+          view = calendar.view
           expect(view.currentStart).toEqualDate('2014-06-01')
           expect(view.currentEnd).toEqualDate('2014-07-01')
         })
@@ -214,11 +217,12 @@ describe('current date', function() {
     })
     describeWhenInDay(function() {
       it('should display the next visible day', function() {
-        var options = {}
-        options.now = options.defaultDate = '2014-06-01' // a Sunday
-        options.weekends = false
-        initCalendar(options)
-        var view = currentCalendar.view
+        let calendar = initCalendar({
+          now: '2014-06-01', // a Sunday
+          defaultDate: '2014-06-01', // a Sunday
+          weekends: false
+        })
+        let view = calendar.view
         expect(view.activeStart).toEqualDate('2014-06-02')
         expect(view.activeEnd).toEqualDate('2014-06-03')
         expect(view.currentStart).toEqualDate('2014-06-02')
@@ -252,10 +256,10 @@ describe('current date', function() {
     })
   }
 
-  function expectViewDates(start, end, titleStart, titleEnd) {
-    var view = currentCalendar.view
-    var calculatedEnd
-    var title
+  function expectViewDates(calendar, start, end, titleStart, titleEnd) {
+    let view = calendar.view
+    let calculatedEnd
+    let title
 
     if (typeof start === 'string') {
       start = new Date(start)
@@ -279,16 +283,17 @@ describe('current date', function() {
     titleEnd = titleEnd || calculatedEnd
 
     if (titleEnd) {
-      title = currentCalendar.formatRange(
+      title = calendar.formatRange(
         titleStart,
         titleEnd,
         TITLE_FORMAT
       )
     } else {
-      title = currentCalendar.formatDate(titleStart, TITLE_FORMAT)
+      title = calendar.formatDate(titleStart, TITLE_FORMAT)
     }
 
-    expect($('.fc-toolbar h2')).toContainText(title)
+    let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+    expect(toolbarWrapper.getTitleText()).toBe(title)
   }
 
 })

+ 0 - 20
packages/__tests__/src/legacy/daygrid-view.js

@@ -1,20 +0,0 @@
-
-describe('dayGrid view rendering', function() {
-
-  pushOptions({
-    defaultView: 'dayGridMonth'
-  })
-
-  it('should have days ordered sun to sat', function() {
-    initCalendar()
-    var fc = $(currentCalendar.el).find('.fc-day-header')
-    expect(fc[0]).toHaveClass('fc-sun')
-    expect(fc[1]).toHaveClass('fc-mon')
-    expect(fc[2]).toHaveClass('fc-tue')
-    expect(fc[3]).toHaveClass('fc-wed')
-    expect(fc[4]).toHaveClass('fc-thu')
-    expect(fc[5]).toHaveClass('fc-fri')
-    expect(fc[6]).toHaveClass('fc-sat')
-  })
-
-})

+ 11 - 9
packages/__tests__/src/legacy/event-coloring.js

@@ -1,13 +1,13 @@
 import { RED_REGEX } from '../lib/dom-misc'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
 
 describe('event coloring', function() {
-
   pushOptions({
-    defaultDate: '2014-11-04'
+    defaultDate: '2014-11-04',
+    allDaySlot: false
   })
 
   describe('when in month view', function() {
-
     pushOptions({
       defaultView: 'dayGridMonth'
     })
@@ -16,10 +16,8 @@ describe('event coloring', function() {
   })
 
   describe('when in week view', function() {
-
     pushOptions({
-      defaultView: 'timeGridWeek',
-      allDaySlot: false
+      defaultView: 'timeGridWeek'
     })
 
     defineViewTests(true)
@@ -219,8 +217,12 @@ describe('event coloring', function() {
   }
 
   function getEventCss(prop, rendering) {
-    var el = $(rendering === 'background' ? '.fc-bgevent' : '.fc-event')
-    return el.css(prop)
+    let calendarWrapper = new CalendarWrapper(currentCalendar)
+    let eventEl = rendering === 'background'
+      ? calendarWrapper.getBgEventEls()[0]
+      : calendarWrapper.getEventEls()[0]
+
+    return $(eventEl).css(prop)
   }
 
   function getTestEvent(defaultOptions, extraOptions) {
@@ -240,6 +242,6 @@ describe('event coloring', function() {
       options.start += 'T01:00:00'
     }
     return options
-  };
+  }
 
 })

+ 36 - 132
packages/__tests__/src/legacy/firstDay.js

@@ -1,12 +1,13 @@
 import enGbLocale from '@fullcalendar/core/locales/en-gb'
+import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
 
-describe('First Day', function() {
+describe('firstDay', function() {
 
   describe('when using default settings', function() {
     it('should make Sunday the first day of the week', function() {
-      initCalendar()
-      var dayFirst = $('.fc-day-header')[0]
-      expect(dayFirst).toHaveClass('fc-sun')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 0)
     })
   })
 
@@ -14,16 +15,10 @@ describe('First Day', function() {
     pushOptions({
       firstDay: 0
     })
+
     it('should make Sunday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-sun')
-      expect(daysOfWeek[1]).toHaveClass('fc-mon')
-      expect(daysOfWeek[2]).toHaveClass('fc-tue')
-      expect(daysOfWeek[3]).toHaveClass('fc-wed')
-      expect(daysOfWeek[4]).toHaveClass('fc-thu')
-      expect(daysOfWeek[5]).toHaveClass('fc-fri')
-      expect(daysOfWeek[6]).toHaveClass('fc-sat')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 0)
     })
   })
 
@@ -31,16 +26,10 @@ describe('First Day', function() {
     pushOptions({
       firstDay: 1
     })
+
     it('should make Monday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-mon')
-      expect(daysOfWeek[1]).toHaveClass('fc-tue')
-      expect(daysOfWeek[2]).toHaveClass('fc-wed')
-      expect(daysOfWeek[3]).toHaveClass('fc-thu')
-      expect(daysOfWeek[4]).toHaveClass('fc-fri')
-      expect(daysOfWeek[5]).toHaveClass('fc-sat')
-      expect(daysOfWeek[6]).toHaveClass('fc-sun')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 1)
     })
   })
 
@@ -48,16 +37,10 @@ describe('First Day', function() {
     pushOptions({
       weekNumberCalculation: 'ISO'
     })
+
     it('should make Monday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-mon')
-      expect(daysOfWeek[1]).toHaveClass('fc-tue')
-      expect(daysOfWeek[2]).toHaveClass('fc-wed')
-      expect(daysOfWeek[3]).toHaveClass('fc-thu')
-      expect(daysOfWeek[4]).toHaveClass('fc-fri')
-      expect(daysOfWeek[5]).toHaveClass('fc-sat')
-      expect(daysOfWeek[6]).toHaveClass('fc-sun')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 1)
     })
   })
 
@@ -68,16 +51,10 @@ describe('First Day', function() {
     pushOptions({
       firstDay: 2
     })
+
     it('should make Tuesday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-tue')
-      expect(daysOfWeek[1]).toHaveClass('fc-wed')
-      expect(daysOfWeek[2]).toHaveClass('fc-thu')
-      expect(daysOfWeek[3]).toHaveClass('fc-fri')
-      expect(daysOfWeek[4]).toHaveClass('fc-sat')
-      expect(daysOfWeek[5]).toHaveClass('fc-sun')
-      expect(daysOfWeek[6]).toHaveClass('fc-mon')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 2)
     })
   })
 
@@ -86,16 +63,10 @@ describe('First Day', function() {
       firstDay: 2,
       weekNumberCalculation: 'ISO'
     })
+
     it('should make Tuesday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-tue')
-      expect(daysOfWeek[1]).toHaveClass('fc-wed')
-      expect(daysOfWeek[2]).toHaveClass('fc-thu')
-      expect(daysOfWeek[3]).toHaveClass('fc-fri')
-      expect(daysOfWeek[4]).toHaveClass('fc-sat')
-      expect(daysOfWeek[5]).toHaveClass('fc-sun')
-      expect(daysOfWeek[6]).toHaveClass('fc-mon')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 2)
     })
   })
 
@@ -103,98 +74,31 @@ describe('First Day', function() {
     pushOptions({
       firstDay: 3
     })
+
     it('should make Wednesday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-wed')
-      expect(daysOfWeek[1]).toHaveClass('fc-thu')
-      expect(daysOfWeek[2]).toHaveClass('fc-fri')
-      expect(daysOfWeek[3]).toHaveClass('fc-sat')
-      expect(daysOfWeek[4]).toHaveClass('fc-sun')
-      expect(daysOfWeek[5]).toHaveClass('fc-mon')
-      expect(daysOfWeek[6]).toHaveClass('fc-tue')
+      let calendar = initCalendar()
+      expectDowStartAt(calendar, 3)
     })
   })
 
-  describe('when setting firstDay to 4', function() {
-    pushOptions({
-      firstDay: 4
-    })
-    it('should make Thursday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-thu')
-      expect(daysOfWeek[1]).toHaveClass('fc-fri')
-      expect(daysOfWeek[2]).toHaveClass('fc-sat')
-      expect(daysOfWeek[3]).toHaveClass('fc-sun')
-      expect(daysOfWeek[4]).toHaveClass('fc-mon')
-      expect(daysOfWeek[5]).toHaveClass('fc-tue')
-      expect(daysOfWeek[6]).toHaveClass('fc-wed')
+  it('should have a different default value based on the locale', function() {
+    let calendar = initCalendar({
+      locale: enGbLocale
     })
+    // firstDay will be 1 (Monday) in Great Britain
+    expectDowStartAt(calendar, 1)
   })
 
-  describe('when setting firstDay to 5', function() {
-    pushOptions({
-      firstDay: 5
-    })
-    it('should make Friday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-fri')
-      expect(daysOfWeek[1]).toHaveClass('fc-sat')
-      expect(daysOfWeek[2]).toHaveClass('fc-sun')
-      expect(daysOfWeek[3]).toHaveClass('fc-mon')
-      expect(daysOfWeek[4]).toHaveClass('fc-tue')
-      expect(daysOfWeek[5]).toHaveClass('fc-wed')
-      expect(daysOfWeek[6]).toHaveClass('fc-thu')
-    })
-  })
 
-  describe('when setting firstDay to 6', function() {
-    pushOptions({
-      firstDay: 6
-    })
-    it('should make Saturday the first day of the week', function() {
-      initCalendar()
-      var daysOfWeek = $('.fc-day-header')
-      expect(daysOfWeek[0]).toHaveClass('fc-sat')
-      expect(daysOfWeek[1]).toHaveClass('fc-sun')
-      expect(daysOfWeek[2]).toHaveClass('fc-mon')
-      expect(daysOfWeek[3]).toHaveClass('fc-tue')
-      expect(daysOfWeek[4]).toHaveClass('fc-wed')
-      expect(daysOfWeek[5]).toHaveClass('fc-thu')
-      expect(daysOfWeek[6]).toHaveClass('fc-fri')
-    })
-  })
+  const DOW_CLASSNAMES = CalendarWrapper.DOW_CLASSNAMES
 
-  describe('when new firstDay options are set', function() {
-    it('should change the first day of week to Monday', function() {
-      initCalendar({
-        firstDay: 1
-      })
-      expect($('.fc-day-header')[0]).toHaveClass('fc-mon')
-    })
-    it('should change the first day of week to Thursday', function() {
-      initCalendar({
-        firstDay: 4
-      })
-      expect($('.fc-day-header')[0]).toHaveClass('fc-thu')
-    })
-  })
+  function expectDowStartAt(calendar, dowNum) {
+    let headerWrapper = new DayGridViewWrapper(calendar).header
+    let cellEls = headerWrapper.getCellEls()
 
-  it('should have a different default value based on the locale', function() {
-    initCalendar({
-      locale: enGbLocale
-    })
-    // firstDay will be 1 (Monday) in Great Britain
-    var daysOfWeek = $('.fc-day-header')
-    expect(daysOfWeek[0]).toHaveClass('fc-mon')
-    expect(daysOfWeek[1]).toHaveClass('fc-tue')
-    expect(daysOfWeek[2]).toHaveClass('fc-wed')
-    expect(daysOfWeek[3]).toHaveClass('fc-thu')
-    expect(daysOfWeek[4]).toHaveClass('fc-fri')
-    expect(daysOfWeek[5]).toHaveClass('fc-sat')
-    expect(daysOfWeek[6]).toHaveClass('fc-sun')
-  })
+    for (let i = 0; i < 7; i++) {
+      expect(cellEls[i]).toHaveClass(DOW_CLASSNAMES[(i + dowNum) % 7])
+    }
+  }
 
 })

+ 83 - 75
packages/__tests__/src/legacy/header-rendering.js

@@ -1,100 +1,107 @@
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
+
 describe('header rendering', function() {
 
-  describe('when using default header options', function() {
-    it('should have title as default on left', function() {
-      initCalendar()
-      expect($('.fc-toolbar > .fc-left > *', currentCalendar.el)).toBeMatchedBy('h2')
-    })
-    it('should have empty center', function() {
-      initCalendar()
-      var center = $('.fc-toolbar > .fc-center', currentCalendar.el)
-      expect(center).toBeEmpty()
-    })
-    it('should have right with today|space|left|right', function() {
-      initCalendar()
-      var rightChildren = $('.fc-toolbar > .fc-right > *', currentCalendar.el)
-      var todayButton = rightChildren.eq(0)
-      var buttonGroup = rightChildren.eq(1)
-      var prevNextButtons = buttonGroup.children()
-      expect(todayButton).toHaveClass('fc-today-button')
-      expect(buttonGroup).toHaveClass('fc-button-group')
-      expect(prevNextButtons.eq(0)).toHaveClass('fc-prev-button')
-      expect(prevNextButtons.eq(1)).toHaveClass('fc-next-button')
-    })
+  it('renders the default header option', function() {
+    let calendar = initCalendar()
+    let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+
+    expect(toolbarWrapper.getSectionContent('left')).toEqual(
+      [ { type: 'title' } ]
+    )
+
+    expect(toolbarWrapper.getSectionContent('center')).toEqual([])
+
+    expect(toolbarWrapper.getSectionContent('right')).toEqual([
+      { type: 'button', name: 'today' },
+      { type: 'button-group', children: [
+        { type: 'button', name: 'prev' },
+        { type: 'button', name: 'next' }
+      ] }
+    ])
   })
 
-  describe('when supplying header options', function() {
-    pushOptions({
+  it('renders a given header option', function() {
+    let calendar = initCalendar({
       header: {
         left: 'next,prev',
         center: 'prevYear today nextYear timeGridDay,timeGridWeek',
         right: 'title'
       }
     })
-    it('should have title on the right', function() {
-      initCalendar()
-      expect($('.fc-toolbar > .fc-right > *', currentCalendar.el)).toBeMatchedBy('h2')
-    })
-    it('should have next|prev on left', function() {
-      initCalendar()
-      var buttonGroup = $('.fc-toolbar > .fc-left > *', currentCalendar.el)
-      var prevNextButtons = buttonGroup.children()
-      expect(prevNextButtons.eq(0)).toHaveClass('fc-next-button')
-      expect(prevNextButtons.eq(1)).toHaveClass('fc-prev-button')
-    })
-    it('should have prevYear|space|today|space|nextYear in center', function() {
-      initCalendar()
-      var items = $('.fc-toolbar > .fc-center > *', currentCalendar.el)
-      expect(items.eq(0)).toHaveClass('fc-prevYear-button')
-      expect(items.eq(1)).toHaveClass('fc-today-button')
-      expect(items.eq(2)).toHaveClass('fc-nextYear-button')
-    })
+    let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+
+    expect(toolbarWrapper.getSectionContent('left')).toEqual([
+      { type: 'button-group', children: [
+        { type: 'button', name: 'next' },
+        { type: 'button', name: 'prev' }
+      ] }
+    ])
+
+    expect(toolbarWrapper.getSectionContent('center')).toEqual([
+      { type: 'button', name: 'prevYear' },
+      { type: 'button', name: 'today' },
+      { type: 'button', name: 'nextYear' },
+      { type: 'button-group', children: [
+        { type: 'button', name: 'timeGridDay' },
+        { type: 'button', name: 'timeGridWeek' }
+      ] }
+    ])
+
+    expect(toolbarWrapper.getSectionContent('right')).toEqual([
+      { type: 'title' }
+    ])
   })
 
   describe('when setting header to false', function() {
     pushOptions({
       header: false
     })
+
     it('should not have header table', function() {
-      initCalendar()
-      expect($('.fc-toolbar')).not.toBeInDOM()
+      let calendar = initCalendar()
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+
+      expect(toolbarWrapper).toBeFalsy()
     })
   })
 
   it('allow for dynamically changing', function() {
-    initCalendar()
-    expect($('.fc-toolbar')).toBeInDOM()
-    currentCalendar.setOption('header', false)
-    expect($('.fc-toolbar')).not.toBeInDOM()
+    let calendar = initCalendar()
+    let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+    expect(toolbarWrapper).toBeTruthy()
+
+    calendar.setOption('header', false)
+    toolbarWrapper = new CalendarWrapper(calendar).toolbar
+    expect(toolbarWrapper).toBeFalsy()
   })
 
-  describe('renders left and right literally', function() {
-    [ 'ltr', 'rtl' ].forEach(function(dir) {
-      describe('when dir is ' + dir, function() {
-        pushOptions({
-          header: {
-            left: 'prev',
-            center: 'today',
-            right: 'next'
-          },
-          dir
-        })
-        it('should have prev in left', function() {
-          initCalendar()
-          var fcHeaderLeft = $('.fc-toolbar > .fc-left', currentCalendar.el)
-          expect(fcHeaderLeft).toContainElement('.fc-prev-button')
-        })
-        it('should have today in center', function() {
-          initCalendar()
-          var fcHeaderCenter = $('.fc-toolbar > .fc-center', currentCalendar.el)
-          expect(fcHeaderCenter).toContainElement('.fc-today-button')
-        })
-        it('should have next in right', function() {
-          initCalendar()
-          var fcHeaderRight = $('.fc-toolbar > .fc-right', currentCalendar.el)
-          expect(fcHeaderRight).toContainElement('.fc-next-button')
-        })
+  describeOptions('dir', {
+    'when dir is LTR': 'ltr',
+    'when dir is RTL': 'rtl'
+  }, function() {
+
+    it('renders left and right literally', function() {
+      let calendar = initCalendar({
+        header: {
+          left: 'prev',
+          center: 'today',
+          right: 'next'
+        }
       })
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+
+      expect(toolbarWrapper.getSectionContent('left')).toEqual([
+        { type: 'button', name: 'prev' }
+      ])
+
+      expect(toolbarWrapper.getSectionContent('center')).toEqual([
+        { type: 'button', name: 'today' }
+      ])
+
+      expect(toolbarWrapper.getSectionContent('right')).toEqual([
+        { type: 'button', name: 'next' }
+      ])
     })
   })
 
@@ -119,14 +126,15 @@ describe('header rendering', function() {
         $(window).off('beforeunload', beforeUnloadHandler)
       }
 
-      initCalendar({
+      let calendar = initCalendar({
         header: {
           left: 'prev,next',
           right: 'title'
         }
       }, el)
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
 
-      $('.fc-next-button').simulate('click')
+      $(toolbarWrapper.getButtonEl('next')).simulate('click')
       setTimeout(function() { // wait to see if handler was called
 
         expect(unloadCalled).toBe(false)

+ 18 - 12
packages/__tests__/src/legacy/locale.js

@@ -1,6 +1,8 @@
 import esLocale from '@fullcalendar/core/locales/es'
 import frLocale from '@fullcalendar/core/locales/fr'
 import arLocale from '@fullcalendar/core/locales/ar'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
+import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
 
 describe('locale', function() {
   pushOptions({
@@ -8,7 +10,7 @@ describe('locale', function() {
   })
 
   it('works when certain locale has no FC settings defined', function() {
-    initCalendar({
+    let calendar = initCalendar({
       locale: 'en-asdf',
       defaultView: 'timeGridWeek',
       defaultDate: '2014-12-25',
@@ -16,29 +18,33 @@ describe('locale', function() {
         { title: 'Christmas', start: '2014-12-25T10:00:00' }
       ]
     })
-    expect(
-      $('.fc-day-header:first').text()
-    ).toMatch(/^Sun\.? 12[-/ ]21$/)
-    expect($('.fc-event .fc-time')).toHaveText('10:00')
+    let headerWrapper = new TimeGridViewWrapper(calendar).header
+
+    expect(headerWrapper.getCellText(0)).toMatch(/^Sun\.? 12[-/ ]21$/)
+
+    let calendarWrapper = new CalendarWrapper(calendar)
+    let eventEl = calendarWrapper.getFirstEventEl()
+    let eventInfo = calendarWrapper.getEventElInfo(eventEl)
+
+    expect(eventInfo.timeText).toBe('10:00')
   })
 
   it('allows dynamic setting', function() {
-    initCalendar({
+    let calendar = initCalendar({
       locale: 'es',
       defaultDate: '2016-07-10',
       defaultView: 'dayGridMonth'
     })
+    let toolbarWrapper = new CalendarWrapper(calendar).toolbar
 
-    var calendarEl = currentCalendar.el
-
-    expect($('h2', calendarEl)).toHaveText('julio de 2016')
-    expect($(calendarEl)).not.toHaveClass('fc-rtl')
+    expect(toolbarWrapper.getTitleText()).toBe('julio de 2016')
+    expect(calendar.getOption('dir')).toBe('ltr')
 
     currentCalendar.setOption('locale', 'fr')
-    expect($('h2', calendarEl)).toHaveText('juillet 2016')
+    expect(toolbarWrapper.getTitleText()).toBe('juillet 2016')
 
     currentCalendar.setOption('locale', 'ar') // NOTE: we had problems testing for RTL title text
-    expect($(calendarEl)).toHaveClass('fc-rtl')
+    expect(calendar.getOption('dir')).toBe('rtl')
   })
 
 })

+ 16 - 10
packages/__tests__/src/legacy/nextDayThreshold.js

@@ -1,4 +1,5 @@
 import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
+import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
 
 describe('nextDayThreshold', function() {
 
@@ -7,7 +8,7 @@ describe('nextDayThreshold', function() {
   //   TODO: detect 2 or more different types of Duration-ish parsing
 
   it('renders an event before the threshold', function() {
-    initCalendar({
+    let calendar = initCalendar({
       nextDayThreshold: '10:00:00',
       defaultDate: '2014-06',
       defaultView: 'dayGridMonth',
@@ -19,11 +20,11 @@ describe('nextDayThreshold', function() {
         }
       ]
     })
-    expect(renderedDayCount()).toBe(2)
+    expect(renderedDayCount(calendar)).toBe(2)
   })
 
   it('renders an event equal to the threshold', function() {
-    initCalendar({
+    let calendar = initCalendar({
       nextDayThreshold: '10:00:00',
       defaultDate: '2014-06',
       defaultView: 'dayGridMonth',
@@ -35,11 +36,11 @@ describe('nextDayThreshold', function() {
         }
       ]
     })
-    expect(renderedDayCount()).toBe(3)
+    expect(renderedDayCount(calendar)).toBe(3)
   })
 
   it('renders an event after the threshold', function() {
-    initCalendar({
+    let calendar = initCalendar({
       nextDayThreshold: '10:00:00',
       defaultDate: '2014-06',
       defaultView: 'dayGridMonth',
@@ -51,7 +52,7 @@ describe('nextDayThreshold', function() {
         }
       ]
     })
-    expect(renderedDayCount()).toBe(3)
+    expect(renderedDayCount(calendar)).toBe(3)
   })
 
   it('won\'t render an event that ends before the first day\'s threshold', function() {
@@ -70,12 +71,17 @@ describe('nextDayThreshold', function() {
   })
 
 
-  function renderedDayCount() { // assumes only one event on the calendar
-    var cellWidth = $('.fc-sun').outerWidth() // works with dayGrid and timeGrid
-    var totalWidth = 0
-    $('.fc-event').each(function() {
+  function renderedDayCount(calendar) { // assumes only one event on the calendar
+    let headerWrapper = new DayGridViewWrapper(calendar).header
+    let dayEl = headerWrapper.getCellEl(0)
+    let cellWidth = $(dayEl).outerWidth() // works with dayGrid and timeGrid
+    let totalWidth = 0
+
+    let eventEls = new CalendarWrapper(calendar).getEventEls()
+    $(eventEls).each(function() {
       totalWidth += $(this).outerWidth()
     })
+
     return Math.round(totalWidth / cellWidth)
   }
 

+ 41 - 62
packages/__tests__/src/legacy/nowIndicator.js

@@ -1,86 +1,63 @@
 import { getBoundingRect } from '../lib/dom-geom'
-import { isElWithinRtl } from '../lib/dom-misc'
 import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
 
 describe('now indicator', function() {
-  var options
-
-  beforeEach(function() {
-    options = {
-      now: '2015-12-26T06:00:00',
-      scrollTime: '00:00'
-    }
+  pushOptions({
+    now: '2015-12-26T06:00:00',
+    scrollTime: '00:00',
+    defaultView: 'timeGridWeek'
   })
 
-  describe('when in month view', function() {
-    beforeEach(function() {
-      options.defaultView = 'dayGridMonth'
-    })
-
-    it('doesn\'t render even when activated', function() {
-      initCalendar(options)
-      expect(isNowIndicatorRendered()).toBe(false)
-    })
+  it('doesn\'t render by default', function() {
+    let calendar = initCalendar()
+    let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+    expect(timeGridWrapper.hasNowIndicator()).toBe(false)
   })
 
-  describe('when in week view', function() {
-    beforeEach(function() {
-      options.defaultView = 'timeGridWeek'
-    })
-
-    it('doesn\'t render by default', function() {
-      initCalendar(options)
-      expect(isNowIndicatorRendered()).toBe(false)
+  describe('when activated', function() {
+    pushOptions({
+      nowIndicator: true
     })
 
-    describe('when activated', function() {
-      beforeEach(function() {
-        options.nowIndicator = true
-      });
+    describeOptions('dir', {
+      'when LTR': 'ltr',
+      'when RTL': 'rtl'
+    }, function() {
 
-      [ 'ltr', 'rtl' ].forEach(function(dir) {
-
-        describe('when ' + dir, function() {
-          beforeEach(function() {
-            options.dir = dir
-          })
-
-          it('doesn\'t render when out of view', function() {
-            options.defaultDate = '2015-12-27' // sun of next week
-            initCalendar(options)
-            expect(isNowIndicatorRendered()).toBe(false)
-          })
+      it('doesn\'t render when out of view', function() {
+        let calendar = initCalendar({
+          defaultDate: '2015-12-27' // sun of next week
+        })
+        let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        expect(timeGridWrapper.hasNowIndicator()).toBe(false)
+      })
 
-          it('renders on correct time', function() {
-            let calendar = initCalendar(options)
-            isNowIndicatorRenderedAt(calendar, '2015-12-26T06:00:00Z')
-          })
+      it('renders on correct time', function() {
+        let calendar = initCalendar()
+        isNowIndicatorRenderedAt(calendar, '2015-12-26T06:00:00Z')
+      })
 
-          it('renders on correct time2', function() {
-            options.now = '2015-12-20T02:30:00'
-            let calendar = initCalendar(options)
-            isNowIndicatorRenderedAt(calendar, '2015-12-20T02:30:00Z')
-          })
+      it('renders on correct time2', function() {
+        let calendar = initCalendar({
+          now: '2015-12-20T02:30:00'
         })
+        isNowIndicatorRenderedAt(calendar, '2015-12-20T02:30:00Z')
       })
     })
   })
 
-  function isNowIndicatorRendered() {
-    return $('.fc-now-indicator').length > 0
-  }
 
   function isNowIndicatorRenderedAt(calendar, date) {
     let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
-    var line = timeGridWrapper.getLine(date)
-    var lineEl = $('.fc-now-indicator-line')
-    var arrowEl = $('.fc-now-indicator-arrow')
+    let line = timeGridWrapper.getLine(date)
+    let lineEl = timeGridWrapper.getNowIndicatorLineEl()
+    let arrowEl = timeGridWrapper.getNowIndicatorArrowEl()
 
-    expect(lineEl.length).toBe(1)
-    expect(arrowEl.length).toBe(1)
+    expect(lineEl).toBeTruthy()
+    expect(arrowEl).toBeTruthy()
 
-    var lineElRect = getBoundingRect(lineEl)
-    var arrowElRect = getBoundingRect(arrowEl)
+    let lineElRect = getBoundingRect(lineEl)
+    let arrowElRect = getBoundingRect(arrowEl)
 
     expect(Math.abs(
       (lineElRect.top + lineElRect.bottom) / 2 -
@@ -91,11 +68,13 @@ describe('now indicator', function() {
       line.top
     )).toBeLessThan(2)
 
-    var timeGridRect = getBoundingRect('.fc-time-grid')
-    if (isElWithinRtl(arrowEl)) {
+    let timeGridRect = getBoundingRect(timeGridWrapper.el)
+
+    if (calendar.getOption('dir') === 'rtl') {
       expect(Math.abs(
         arrowElRect.right - timeGridRect.right
       )).toBeLessThan(2)
+
     } else {
       expect(Math.abs(
         arrowElRect.left - timeGridRect.left

+ 16 - 11
packages/__tests__/src/legacy/removeEventSources.js

@@ -1,5 +1,6 @@
-describe('removeEventSources', function() {
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
 
+describe('removeEventSources', function() {
   pushOptions({
     defaultDate: '2014-08-01',
     defaultView: 'timeGridDay',
@@ -10,28 +11,32 @@ describe('removeEventSources', function() {
     ]
   })
 
-  describe('when called with no arguments', function() { //
+  describe('when called with no arguments', function() {
+
     it('removes all sources', function() {
+      let calendar = initCalendar()
+      let calendarWrapper = new CalendarWrapper(calendar)
 
-      initCalendar()
-      expect($('.fc-event').length).toBe(3)
+      expect(calendarWrapper.getEventEls().length).toBe(3)
 
-      currentCalendar.removeAllEventSources()
+      calendar.removeAllEventSources()
 
-      expect($('.fc-event').length).toBe(0)
+      expect(calendarWrapper.getEventEls().length).toBe(0)
     })
   })
 
   describe('when called with specific IDs', function() {
+
     it('removes only events with matching sources', function() {
+      let calendar = initCalendar()
+      let calendarWrapper = new CalendarWrapper(calendar)
 
-      initCalendar()
-      expect($('.fc-event').length).toBe(3)
+      expect(calendarWrapper.getEventEls().length).toBe(3)
 
-      currentCalendar.getEventSourceById(1).remove()
-      currentCalendar.getEventSourceById(3).remove()
+      calendar.getEventSourceById(1).remove()
+      calendar.getEventSourceById(3).remove()
 
-      expect($('.fc-event').length).toBe(1)
+      expect(calendarWrapper.getEventEls().length).toBe(1)
       expect($('.event2').length).toBe(1)
     })
   })

+ 26 - 34
packages/__tests__/src/legacy/scroll-state.js

@@ -1,5 +1,9 @@
+import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
+import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
+
 describe('scroll state', function() {
-  var calendarEl
+  let calendarEl
 
   beforeEach(function() {
     calendarEl = $('<div id="calendar">').width(800).appendTo('body')
@@ -11,66 +15,54 @@ describe('scroll state', function() {
 
   pushOptions({
     defaultDate: '2015-02-20',
-    contentHeight: 200
+    contentHeight: 200,
+    scrollTime: '00:00' // for timeGrid
   })
 
-  describe('when in month view', function() {
-    pushOptions({
-      defaultView: 'dayGridMonth'
-    })
-    defineTests()
-  })
-
-  describe('when in week view', function() {
-    pushOptions({
-      defaultView: 'timeGridWeek',
-      scrollTime: '00:00'
-    })
-    defineTests()
-  })
-
-  function defineTests() {
+  describeOptions('defaultView', {
+    'when in month view': 'dayGridMonth',
+    'when in week view': 'timeGridWeek'
+  }, function(viewName) {
+    let ViewWrapper = viewName.match(/^dayGrid/) ? DayGridViewWrapper : TimeGridViewWrapper
 
     it('should be maintained when resizing window', function(done) {
-      var scrollEl
-      var scroll0
-
-      initCalendar({
+      let calendar = initCalendar({
         windowResize: function() {
           setTimeout(function() { // wait until all other tasks are finished
-            expect(scrollEl.scrollTop()).toBe(scroll0)
+            expect(scrollEl.scrollTop).toBe(scroll0)
             done()
           }, 0)
         }
       }, calendarEl)
-      scrollEl = $('.fc-scroller', calendarEl)
+      let scrollEl = new ViewWrapper(calendar).getScrollerEl()
+      let scroll0
 
       setTimeout(function() { // wait until after browser's scroll state is applied
-        scrollEl.scrollTop(9999) // all the way
-        scroll0 = scrollEl.scrollTop()
+        scrollEl.scrollTop = 9999 // all the way
+        scroll0 = scrollEl.scrollTop
         $(window).simulate('resize')
       }, 0)
     })
 
     it('should be maintained when after rerendering events', function() {
-      initCalendar({
+      let calendar = initCalendar({
         events: [ {
           start: '2015-02-20'
         } ]
       }, calendarEl)
 
-      let scrollEl = $('.fc-scroller', calendarEl)
-      let eventEl0 = $('.fc-event', calendarEl)
+      let scrollEl = new ViewWrapper(calendar).getScrollerEl()
+      let eventEl0 = new CalendarWrapper(calendar).getEventEls()
       expect(eventEl0.length).toBe(1)
 
-      scrollEl.scrollTop(9999) // all the way
-      let scroll0 = scrollEl.scrollTop()
+      scrollEl.scrollTop = 9999 // all the way
+      let scroll0 = scrollEl.scrollTop
       currentCalendar.render()
 
-      let eventEl1 = $('.fc-event', calendarEl)
+      let eventEl1 = new CalendarWrapper(calendar).getEventEls()
       expect(eventEl1.length).toBe(1)
       expect(eventEl1[0]).not.toBe(eventEl0[0]) // ensure it a rerender
-      expect(scrollEl.scrollTop()).toBe(scroll0)
+      expect(scrollEl.scrollTop).toBe(scroll0)
     })
-  }
+  })
 })

+ 9 - 4
packages/__tests__/src/legacy/selectMirror.js

@@ -1,3 +1,5 @@
+import TimeGridViewWrapper from "../lib/wrappers/TimeGridViewWrapper"
+
 describe('selectMirror', function() {
 
   pushOptions({
@@ -8,7 +10,7 @@ describe('selectMirror', function() {
   })
 
   it('goes through eventRender and eventPositioned', function() {
-    initCalendar({
+    let calendar = initCalendar({
       eventRender(arg) {
         expect(arg.isMirror).toBe(true)
         $(arg.el).addClass('eventDidRender')
@@ -19,9 +21,12 @@ describe('selectMirror', function() {
       }
     })
 
-    currentCalendar.select('2014-08-04T01:00:00Z', '2014-08-04T04:00:00Z')
+    calendar.select('2014-08-04T01:00:00Z', '2014-08-04T04:00:00Z')
 
-    expect($('.fc-mirror')).toHaveClass('eventDidRender')
-    expect($('.fc-mirror')).toHaveClass('eventDidPosition')
+    let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+    let mirrorEls = timeGridWrapper.getMirrorEls()
+    expect(mirrorEls.length).toBe(1)
+    expect(mirrorEls[0]).toHaveClass('eventDidRender')
+    expect(mirrorEls[0]).toHaveClass('eventDidPosition')
   })
 })

+ 26 - 14
packages/__tests__/src/legacy/slotDuration.js

@@ -1,44 +1,54 @@
+import TimeGridViewWrapper from "../lib/wrappers/TimeGridViewWrapper"
+
 describe('slotDuration', function() {
 
-  var minutesInADay = 1440
+  const minutesInADay = 1440
 
   describe('when using the default settings', function() {
+
     describe('in week', function() {
       it('should have slots 1440/30 slots', function() {
-        initCalendar({
+        let calendar = initCalendar({
           defaultView: 'timeGridWeek'
         })
-        var slotCount = $('.fc-slats tr').length
+        let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
         expect(slotCount).toEqual(Math.ceil(minutesInADay / 30))
       })
     })
+
     describe('in day', function() {
       it('should have slots 1440/30 slots', function() {
-        initCalendar({
+        let calendar = initCalendar({
           defaultView: 'timeGridDay'
         })
-        var slotCount = $('.fc-slats tr').length
+        let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
         expect(slotCount).toEqual(Math.ceil(minutesInADay / 30))
       })
     })
   })
 
   describe('when slotMinutes is set to 30', function() {
+
     describe('in week', function() {
       it('should have slots 1440/30 slots', function() {
-        initCalendar({
+        let calendar = initCalendar({
           defaultView: 'timeGridWeek'
         })
-        var slotCount = $('.fc-slats tr').length
+        let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
         expect(slotCount).toEqual(Math.ceil(minutesInADay / 30))
       })
     })
+
     describe('in day', function() {
       it('should have slots 1440/30 slots', function() {
-        initCalendar({
+        let calendar = initCalendar({
           defaultView: 'timeGridDay'
         })
-        var slotCount = $('.fc-slats tr').length
+        let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
         expect(slotCount).toEqual(Math.ceil(minutesInADay / 30))
       })
     })
@@ -46,16 +56,17 @@ describe('slotDuration', function() {
 
   describe('when slotMinutes is set to a series of times', function() {
 
-    var slotMinutesList = [ 10, 12, 15, 17, 20, 30, 35, 45, 60, 62, 120, 300 ]
+    const slotMinutesList = [ 10, 12, 15, 17, 20, 30, 35, 45, 60, 62, 120, 300 ]
 
     describe('in week', function() {
       slotMinutesList.forEach(function(slotMinutes) {
         it('should have slots 1440/x slots', function() {
-          initCalendar({
+          let calendar = initCalendar({
             defaultView: 'timeGridWeek',
             slotDuration: { minutes: slotMinutes }
           })
-          var slotCount = $('.fc-slats tr').length
+          let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
           var expected = Math.ceil(minutesInADay / slotMinutes)
           expect(slotCount).toEqual(expected)
         })
@@ -65,11 +76,12 @@ describe('slotDuration', function() {
     describe('in day', function() {
       slotMinutesList.forEach(function(slotMinutes) {
         it('should have slots 1440/x slots', function() {
-          initCalendar({
+          let calendar = initCalendar({
             defaultView: 'timeGridDay',
             slotDuration: { minutes: slotMinutes }
           })
-          var slotCount = $('.fc-slats tr').length
+          let timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
+        let slotCount = timeGridWrapper.getSlotEls().length
           var expected = Math.ceil(minutesInADay / slotMinutes)
           expect(slotCount).toEqual(expected)
         })

+ 48 - 48
packages/__tests__/src/legacy/weekNumberCalculation.js

@@ -1,69 +1,69 @@
+import DayGridViewWrapper from '../lib/wrappers/DayGridViewWrapper'
+import TimeGridViewWrapper from '../lib/wrappers/TimeGridViewWrapper'
 import arLocale from '@fullcalendar/core/locales/ar'
 
 describe('weekNumberCalculation', function() {
-
   pushOptions({
     weekNumbers: true
   })
 
-  function getRenderedWeekText() {
-    // works for both kinds of views
-    return $('.fc-timeGrid-view .fc-week-number, .fc-week:first .fc-content-skeleton .fc-week-number').text()
-  }
-
-  function getRenderedWeekNumber() {
-    var text = getRenderedWeekText() || ''
-    return parseInt(text.replace(/\D/g, ''), 10)
-  }
+  describeOptions('defaultView', {
+    'when in day-grid': 'dayGridDay',
+    'when in time-grid': 'timeGridDay'
+  }, function(viewName) {
 
-  [ 'dayGridDay', 'timeGridDay' ].forEach(function(viewType) {
-    describe('when in ' + viewType + ' view', function() {
-      pushOptions({
-        defaultView: viewType
-      })
+    let getWeekNumberText = viewName.match(/^dayGrid/)
+      ? (calendar) => new DayGridViewWrapper(calendar).dayGrid.getWeekNumberText(0)
+      : (calendar) => new TimeGridViewWrapper(calendar).header.getWeekNumberTitle()
 
-      it('should display the American standard when using \'local\'', function() {
-        initCalendar({
-          defaultDate: '2013-11-23', // a Saturday
-          weekNumberCalculation: 'local'
-        })
-        expect(getRenderedWeekNumber()).toBe(47)
+    it('should display the American standard when using \'local\'', function() {
+      let calendar = initCalendar({
+        defaultDate: '2013-11-23', // a Saturday
+        weekNumberCalculation: 'local'
       })
+      expect(getWeekNumber(calendar)).toBe(47)
+    })
 
-      it('should display a locale-specific local week number', function() {
-        initCalendar({
-          defaultDate: '2013-11-23', // a Saturday
-          locale: arLocale,
-          weekNumberCalculation: 'local'
-        })
-        expect(getRenderedWeekText()).toMatch(/٤٨|48/)
+    it('should display a locale-specific local week number', function() {
+      let calendar = initCalendar({
+        defaultDate: '2013-11-23', // a Saturday
+        locale: arLocale,
+        weekNumberCalculation: 'local'
       })
+      expect(getWeekNumberText(calendar)).toMatch(/٤٨|48/)
+    })
 
-      // another local test, but to make sure it is different from ISO
-      it('should display the American standard when using \'local\'', function() {
-        initCalendar({
-          defaultDate: '2013-11-17', // a Sunday
-          weekNumberCalculation: 'local'
-        })
-        expect(getRenderedWeekNumber()).toBe(47)
+    // another local test, but to make sure it is different from ISO
+    it('should display the American standard when using \'local\'', function() {
+      let calendar = initCalendar({
+        defaultDate: '2013-11-17', // a Sunday
+        weekNumberCalculation: 'local'
       })
+      expect(getWeekNumber(calendar)).toBe(47)
+    })
 
-      it('should display ISO standard when using \'ISO\'', function() {
-        initCalendar({
-          defaultDate: '2013-11-17', // a Sunday
-          weekNumberCalculation: 'ISO'
-        })
-        expect(getRenderedWeekNumber()).toBe(46)
+    it('should display ISO standard when using \'ISO\'', function() {
+      let calendar = initCalendar({
+        defaultDate: '2013-11-17', // a Sunday
+        weekNumberCalculation: 'ISO'
       })
+      expect(getWeekNumber(calendar)).toBe(46)
+    })
 
-      it('should display the calculated number when a custom function', function() {
-        initCalendar({
-          weekNumberCalculation: function() {
-            return 4
-          }
-        })
-        expect(getRenderedWeekNumber()).toBe(4)
+    it('should display the calculated number when a custom function', function() {
+      let calendar = initCalendar({
+        weekNumberCalculation: function() {
+          return 4
+        }
       })
+      expect(getWeekNumber(calendar)).toBe(4)
     })
+
+
+    function getWeekNumber(calendar) {
+      var text = getWeekNumberText(calendar) || ''
+      return parseInt(text.replace(/\D/g, ''), 10)
+    }
+
   })
 })

+ 29 - 56
packages/__tests__/src/legacy/weekNumbers.js

@@ -1,17 +1,8 @@
-describe('weekNumbers', function() {
-
-  var counts
+import { getLegacyWeekNumberCounts } from "../lib/wrappers/DayGridWrapper"
 
-  beforeEach(function() {
-    counts = {}
-  })
-
-  afterEach(function() {
-    currentCalendar.destroy()
-  })
+describe('weekNumbers', function() {
 
   describe('when using month view', function() {
-
     pushOptions({
       defaultView: 'dayGridMonth',
       fixedWeekCount: true // will make 6 rows
@@ -22,7 +13,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should not display week numbers at all', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -32,7 +23,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -42,7 +33,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -60,7 +51,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -70,7 +61,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -80,7 +71,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -96,9 +87,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should display week numbers along the side only', function() {
           initCalendar()
-          counts = getCounts()
-          // TODO: Is it possible to remove class fc-week-number from
-          // headers and fillers, bringing allWeekNumbers down to 6?
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(6)
           expect(counts.cellWeekNumbers).toEqual(0)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -110,9 +99,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
-          // TODO: Is it possible to remove class fc-week-number from
-          // headers and fillers, bringing allWeekNumbers down to 6?
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(6)
           expect(counts.cellWeekNumbers).toEqual(0)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -124,7 +111,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(0)
           expect(counts.cellWeekNumbers).toEqual(6)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -146,7 +133,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should not display week numbers at all', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -156,7 +143,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -166,7 +153,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -182,7 +169,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should not display week numbers at all', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -192,7 +179,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -202,7 +189,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -218,9 +205,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should display week numbers along the side only', function() {
           initCalendar()
-          counts = getCounts()
-          // TODO: Is it possible to remove class fc-week-number from
-          // headers and fillers, bringing allWeekNumbers down to 1?
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(1)
           expect(counts.cellWeekNumbers).toEqual(0)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -232,9 +217,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
-          // TODO: Is it possible to remove class fc-week-number from
-          // headers and fillers, bringing allWeekNumbers down to 1?
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(1)
           expect(counts.cellWeekNumbers).toEqual(0)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -246,7 +229,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.colWeekNumbers).toEqual(0)
           expect(counts.cellWeekNumbers).toEqual(1)
           expect(counts.cornerWeekNumbers).toEqual(0)
@@ -268,7 +251,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should not display week numbers at all', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -278,7 +261,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -288,7 +271,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -304,7 +287,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should not display week numbers at all', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -314,7 +297,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -324,7 +307,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(0)
         })
       })
@@ -340,7 +323,7 @@ describe('weekNumbers', function() {
       describe('and default weekNumbersWithinDays', function() {
         it('should display week numbers in the top left corner only', function() {
           initCalendar()
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(1)
           expect(counts.colWeekNumbers).toEqual(0)
           expect(counts.cellWeekNumbers).toEqual(0)
@@ -353,7 +336,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: false
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(1)
           expect(counts.colWeekNumbers).toEqual(0)
           expect(counts.cellWeekNumbers).toEqual(0)
@@ -366,7 +349,7 @@ describe('weekNumbers', function() {
           initCalendar({
             weekNumbersWithinDays: true
           })
-          counts = getCounts()
+          let counts = getLegacyWeekNumberCounts()
           expect(counts.allWeekNumbers).toEqual(1)
           expect(counts.colWeekNumbers).toEqual(0)
           expect(counts.cellWeekNumbers).toEqual(0)
@@ -378,14 +361,4 @@ describe('weekNumbers', function() {
 
   })
 
-  function getCounts() {
-    var t = {}
-
-    t.allWeekNumbers = $('.fc-week-number').length
-    t.colWeekNumbers = $('.fc-content-skeleton thead td.fc-week-number').length
-    t.cellWeekNumbers = $('.fc-content-skeleton thead .fc-day-top span.fc-week-number').length
-    t.cornerWeekNumbers = $('.fc-head .fc-axis.fc-week-number').length
-
-    return t
-  }
 })

+ 9 - 17
packages/__tests__/src/legacy/weekViewRender.js

@@ -1,6 +1,8 @@
+import TimeGridViewWrapper from "../lib/wrappers/TimeGridViewWrapper"
+
 describe('weekViewRender', function() {
 
-  var nowStr = '2018-05-28'
+  const nowStr = '2018-05-28' // is a Monday
 
   pushOptions({
     now: nowStr,
@@ -9,23 +11,13 @@ describe('weekViewRender', function() {
 
   describe('verify th class for today', function() {
 
-    it('should have fc-today class only on "today"', function() {
-      initCalendar()
-      var foundToday = false
-
-      $('th.fc-day-header', currentCalendar.el).each(function(i, headerNode) {
-        var headerEl = $(headerNode)
-        var dateMatchesToday = headerNode.getAttribute('data-date') === nowStr
-        var hasTodayClass = headerEl.hasClass('fc-today')
-
-        expect(dateMatchesToday).toBe(hasTodayClass)
-
-        if (hasTodayClass) {
-          foundToday = true
-        }
-      })
+    it('should have today class only on "today"', function() {
+      let calendar = initCalendar()
+      let headerWrapper = new TimeGridViewWrapper(calendar).header
+      let cellInfo = headerWrapper.getCellInfo()
 
-      expect(foundToday).toBe(true)
+      expect(cellInfo[1].date).toEqualDate(nowStr)
+      expect(cellInfo[1].isToday).toBe(true)
     })
   })
 })

+ 12 - 8
packages/__tests__/src/lib/dnd-resize-utils.js

@@ -32,7 +32,8 @@ export function testEventDrag(options, dropDate, expectSuccess, callback, eventC
       dropDateHasTime = true
     }
 
-    $eventEl = eventClassName ? $(`.${eventClassName}:first`) : $(new CalendarWrapper(calendar).getFirstEventEl())
+    let calendarWrapper = new CalendarWrapper(calendar)
+    $eventEl = eventClassName ? $(`.${eventClassName}:first`) : $(calendarWrapper.getFirstEventEl())
     expect($eventEl.length).toBe(1)
 
     if (dropDateHasTime) {
@@ -63,7 +64,7 @@ export function testEventDrag(options, dropDate, expectSuccess, callback, eventC
       dx: dx,
       dy: dy,
       onBeforeRelease: function() {
-        allowed = !$('body').hasClass('fc-not-allowed')
+        allowed = calendarWrapper.isAllowingDragging()
         expect(allowed).toBe(expectSuccess)
       },
       onRelease: function() {
@@ -126,8 +127,9 @@ export function testEventResize(options, resizeDate, expectSuccess, callback, ev
       resizeDateHasTime = true
     }
 
+    let calendarWrapper = new CalendarWrapper(calendar)
     $eventEl = eventClassName ? $(`.${eventClassName}:first`) : (() => {
-      let eventEls = new CalendarWrapper(calendar).getEventEls()
+      let eventEls = calendarWrapper.getEventEls()
       return $(eventEls[eventEls.length - 1]) // the last one
     })()
     $dragEl = $eventEl.find('.' + CalendarWrapper.EVENT_RESIZER_CLASSNAME)
@@ -155,7 +157,7 @@ export function testEventResize(options, resizeDate, expectSuccess, callback, ev
       dx: dx,
       dy: dy,
       onBeforeRelease: function() {
-        allowed = !$('body').hasClass('fc-not-allowed')
+        allowed = calendarWrapper.isAllowingDragging()
       },
       onRelease: function() {
         var eventObj
@@ -212,10 +214,12 @@ export function testSelection(options, start, end, expectSuccess, callback) {
       arg.end.valueOf() === end.valueOf()
   }
   spyOn(options, 'select').and.callThrough()
-  initCalendar(options)
+
+  let calendar = initCalendar(options)
+  let calendarWrapper = new CalendarWrapper(calendar)
 
   if (!allDay) {
-    var timeGridWrapper = new TimeGridViewWrapper(currentCalendar).timeGrid
+    var timeGridWrapper = new TimeGridViewWrapper(calendar).timeGrid
     $firstDayEl = $(timeGridWrapper.getDayEls(start))
     $lastDayEl = $(timeGridWrapper.getDayEls(end))
     firstSlatIndex = start.getUTCHours() * 2 + (start.getUTCMinutes() / 30) // assumes slotDuration:'30:00'
@@ -227,7 +231,7 @@ export function testSelection(options, start, end, expectSuccess, callback) {
     dy = $lastSlatEl.offset().top - $firstSlatEl.offset().top
     $dragEl = $firstSlatEl
   } else {
-    var dayGridWrapper = new DayGridViewWrapper(currentCalendar).dayGrid
+    var dayGridWrapper = new DayGridViewWrapper(calendar).dayGrid
     $firstDayEl = $(dayGridWrapper.getDayEl(start))
     $lastDayEl = $(dayGridWrapper.getDayEl(new Date(end.valueOf() - 1))) // inclusive
     dy = $lastDayEl.offset().top - $firstDayEl.offset().top
@@ -242,7 +246,7 @@ export function testSelection(options, start, end, expectSuccess, callback) {
     dx: dx,
     dy: dy,
     onBeforeRelease: function() {
-      allowed = !$('body').hasClass('fc-not-allowed')
+      allowed = calendarWrapper.isAllowingDragging()
     },
     onRelease: function() {
       if (expectSuccess) {

+ 0 - 5
packages/__tests__/src/lib/dom-misc.js

@@ -34,11 +34,6 @@ export function getStockScrollbarWidths(dir) {
 }
 
 
-export function isElWithinRtl(el) {
-  return el.closest('.fc').hasClass('fc-rtl')
-}
-
-
 beforeEach(function() {
   jasmine.addMatchers({
 

+ 6 - 1
packages/__tests__/src/lib/wrappers/CalendarWrapper.ts

@@ -43,7 +43,7 @@ export default class CalendarWrapper {
 
 
   getViewContainerEl() {
-    return this.calendar.el.querySelector('.fc-view-container')
+    return this.calendar.el.querySelector('.fc-view-container') as HTMLElement
   }
 
 
@@ -111,4 +111,9 @@ export default class CalendarWrapper {
   }
 
 
+  isAllowingDragging() {
+    return !$('body').hasClass('fc-not-allowed')
+  }
+
+
 }

+ 25 - 0
packages/__tests__/src/lib/wrappers/DayGridWrapper.ts

@@ -79,6 +79,11 @@ export default class DayGridWrapper {
   }
 
 
+  getMoreEls() {
+    return findElements(this.el, '.fc-more')
+  }
+
+
   getWeekNavLinkEls(isEmbedded) { // along the sides of the row
     return isEmbedded
       ? findElements(this.el, '.fc-day-top a.fc-week-number')
@@ -86,6 +91,16 @@ export default class DayGridWrapper {
   }
 
 
+  getWeekCell(rowIndex) {
+    return this.el.querySelector(`.fc-row:nth-child(${rowIndex + 1}) td.fc-week-number`)
+  }
+
+
+  getWeekNumberText(rowIndex) {
+    return $(this.el.querySelector(`.fc-row:nth-child(${rowIndex + 1}) .fc-content-skeleton thead td.fc-week-number`)).text()
+  }
+
+
   getNavLinkEl(date) {
     if (typeof date === 'string') {
       date = new Date(date)
@@ -302,3 +317,13 @@ export default class DayGridWrapper {
   }
 
 }
+
+
+export function getLegacyWeekNumberCounts() {
+  return {
+    allWeekNumbers: $('.fc-week-number').length,
+    colWeekNumbers: $('.fc-content-skeleton thead td.fc-week-number').length,
+    cellWeekNumbers: $('.fc-content-skeleton thead .fc-day-top span.fc-week-number').length, // within-the-cell
+    cornerWeekNumbers: $('.fc-head .fc-axis.fc-week-number').length
+  }
+}

+ 9 - 0
packages/__tests__/src/lib/wrappers/DayHeaderWrapper.ts

@@ -42,6 +42,15 @@ export default class DayHeaderWrapper {
   }
 
 
+  getCellInfo() { // all
+    return this.getCellEls().map((cellEl) => ({
+      text: $(cellEl).text(),
+      date: parseIsoAsUtc(cellEl.getAttribute('data-date')),
+      isToday: cellEl.classList.contains('fc-today')
+    }))
+  }
+
+
   getAxisEl() {
     return this.el.querySelector('.fc-axis')
   }

+ 20 - 5
packages/__tests__/src/lib/wrappers/TimeGridWrapper.ts

@@ -97,10 +97,24 @@ export default class TimeGridWrapper {
 
 
   hasNowIndicator() {
-    return Boolean(
-      this.el.querySelector('.fc-now-indicator-arrow') &&
-      this.el.querySelector('.fc-now-indicator-line')
-    )
+    let hasArrow = Boolean(this.getNowIndicatorArrowEl())
+    let hasLine = Boolean(this.getNowIndicatorLineEl())
+
+    if (hasArrow !== hasLine) {
+      throw new Error('Inconsistent now-indicator rendering state')
+    } else {
+      return hasArrow
+    }
+  }
+
+
+  getNowIndicatorArrowEl() {
+    return this.el.querySelector('.fc-now-indicator-arrow')
+  }
+
+
+  getNowIndicatorLineEl() {
+    return this.el.querySelector('.fc-now-indicator-line')
   }
 
 
@@ -617,6 +631,7 @@ function checkEventRenderingMatch(expectedRects, eventEls) {
 
 export function queryEventElInfo(eventEl: HTMLElement) {
   return {
-    timeText: $(eventEl.querySelector('.fc-time')).text()
+    timeText: $(eventEl.querySelector('.fc-time')).text(),
+    isShort: eventEl.classList.contains('fc-short')
   }
 }

+ 33 - 1
packages/__tests__/src/lib/wrappers/ToolbarWrapper.ts

@@ -16,7 +16,7 @@ export default class ToolbarWrapper {
 
     if (el) {
       let iconEl = el.querySelector(`.${iconPrefix}`)
-      let iconNameMatch = iconEl && iconEl.className.match(new RegExp(`${iconPrefix}-(\\w+)`))
+      let iconNameMatch = iconEl && iconEl.className.match(new RegExp(`${iconPrefix}-([^ ]+)`))
 
       return {
         text: $(el).text(),
@@ -36,4 +36,36 @@ export default class ToolbarWrapper {
     return this.el.querySelector('h2').innerText.trim()
   }
 
+
+  getSectionContent(sectionName) { // sectionName like left/center/right
+    let sectionEl = this.el.querySelector(`.fc-${sectionName}`) as HTMLElement
+
+    return processSectionItems(sectionEl)
+  }
+
+}
+
+
+function processSectionItems(sectionEl: HTMLElement) {
+  let children = Array.prototype.slice.call(sectionEl.children) as HTMLElement[]
+
+  return children.map((childEl) => {
+    if (childEl.classList.contains('fc-button')) {
+      return {
+        type: 'button',
+        name: childEl.className.match(/fc-(\w+)-button/)[1]
+      }
+    } else if (childEl.classList.contains('fc-button-group')) {
+      return {
+        type: 'button-group',
+        children: processSectionItems(childEl)
+      }
+    } else if (childEl.nodeName === 'H2') {
+      return {
+        type: 'title'
+      }
+    } else {
+      throw new Error('Unknown type of content in header')
+    }
+  })
 }

+ 15 - 8
packages/__tests__/src/theme/bootstrap4.js

@@ -1,5 +1,6 @@
 import BootstrapPlugin from '@fullcalendar/bootstrap'
 import DayGridPlugin from '@fullcalendar/daygrid'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
 
 describe('bootstrap theme', function() {
   pushOptions({
@@ -13,26 +14,32 @@ describe('bootstrap theme', function() {
     })
 
     it('renders default', function() {
-      initCalendar()
-      expect($('.fa')).toHaveClass('fa-chevron-right')
+      let calendar = initCalendar()
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+      let buttonInfo = toolbarWrapper.getButtonInfo('next', 'fa')
+
+      expect(buttonInfo.iconName).toBe('chevron-right')
     })
 
     it('renders a customized icon', function() {
-      initCalendar({
+      let calendar = initCalendar({
         bootstrapFontAwesome: {
           next: 'asdf'
         }
       })
-      expect($('.fa')).toHaveClass('fa-asdf')
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+      let buttonInfo = toolbarWrapper.getButtonInfo('next', 'fa')
+
+      expect(buttonInfo.iconName).toBe('asdf')
     })
 
     it('renders text when specified as false', function() {
-      initCalendar({
+      let calendar = initCalendar({
         bootstrapFontAwesome: false
       })
-      expect($('.fa')).not.toBeInDOM()
-      expect($('.fc-next-button')).toHaveText('next')
+      let toolbarWrapper = new CalendarWrapper(calendar).toolbar
+
+      expect(toolbarWrapper.getButtonInfo('next', 'fa').iconName).toBeFalsy()
     })
   })
-
 })

+ 12 - 11
packages/__tests__/src/theme/switching.js

@@ -1,5 +1,6 @@
 import BootstrapPlugin from '@fullcalendar/bootstrap'
 import DayGridPlugin from '@fullcalendar/daygrid'
+import CalendarWrapper from '../lib/wrappers/CalendarWrapper'
 
 describe('theme switching', function() {
   pushOptions({
@@ -7,27 +8,27 @@ describe('theme switching', function() {
   })
 
   it('can switch from standard to bootstrap', function() {
-    initCalendar()
-    verifyStandardTheme()
+    let calendar = initCalendar()
+    verifyStandardTheme(calendar)
     currentCalendar.setOption('themeSystem', 'bootstrap')
-    verifyBootstrapTheme()
+    verifyBootstrapTheme(calendar)
   })
 
   it('can switch from bootstrap to standard', function() {
-    initCalendar({ themeSystem: 'bootstrap' })
-    verifyBootstrapTheme()
+    let calendar = initCalendar({ themeSystem: 'bootstrap' })
+    verifyBootstrapTheme(calendar)
     currentCalendar.setOption('themeSystem', 'standard')
-    verifyStandardTheme()
+    verifyStandardTheme(calendar)
   })
 
 
-  function verifyStandardTheme() {
-    expect($('.fc-unthemed')).toBeInDOM()
+  function verifyStandardTheme(calendar) {
+    expect(calendar.el).toHaveClass(CalendarWrapper.UNTHEMED_CLASSNAME)
   }
 
-  function verifyBootstrapTheme() {
-    expect($('.fc-bootstrap')).toBeInDOM()
-    expect($('.fc .table-bordered')).toBeInDOM()
+
+  function verifyBootstrapTheme(calendar) {
+    expect(calendar.el).toHaveClass(CalendarWrapper.BOOTSTRAP_CLASSNAME)
   }
 
 })

+ 7 - 8
packages/__tests__/src/view-render/rerender.js

@@ -1,8 +1,9 @@
+import DayGridViewWrapper from "../lib/wrappers/DayGridViewWrapper"
 
 describe('rerendering a calendar', function() {
 
   it('keeps sizing', function() {
-    initCalendar({
+    let calendar = initCalendar({
       defaultView: 'dayGridMonth',
       defaultDate: '2019-08-08',
       eventLimit: 3,
@@ -13,14 +14,12 @@ describe('rerendering a calendar', function() {
         { date: '2019-08-08', title: 'event' }
       ]
     })
+    let dayGridWrapper = new DayGridViewWrapper(calendar).dayGrid
 
-    expect(getMoreLinkCnt()).toBe(1)
-    currentCalendar.render()
-    expect(getMoreLinkCnt()).toBe(1) // good way to test that sizing is maintained
-  })
+    expect(dayGridWrapper.getMoreEls().length).toBe(1)
 
-  function getMoreLinkCnt() {
-    return $('.fc-more').length
-  }
+    calendar.render()
+    expect(dayGridWrapper.getMoreEls().length).toBe(1) // good way to test that sizing is maintained
+  })
 
 })

+ 9 - 6
packages/__tests__/src/view-render/scrollToTime.js

@@ -1,19 +1,22 @@
+import TimeGridViewWrapper from "../lib/wrappers/TimeGridViewWrapper"
+
 describe('scrollToTime method', function() {
 
   it('accepts a object duration input', function() {
-    initCalendar({
+    let calendar = initCalendar({
       scrollTime: 0,
       defaultView: 'timeGridWeek'
     })
+    let viewWrapper = new TimeGridViewWrapper(calendar)
 
-    currentCalendar.scrollToTime({ hours: 2 })
+    calendar.scrollToTime({ hours: 2 })
 
     // NOTE: c&p'd from scrollTime tests
-    var slotCell = $('.fc-slats tr:eq(4)') // 2am slot
-    var slotTop = slotCell.position().top
-    var scrollContainer = $('.scrollgrid .fc-body:last-child .fc-scroller')
-    var scrollTop = scrollContainer.scrollTop()
+    var slotTop = viewWrapper.timeGrid.getTimeTop('02:00:00') - viewWrapper.timeGrid.el.getBoundingClientRect().top
+    var scrollEl = viewWrapper.getScrollerEl()
+    var scrollTop = scrollEl.scrollTop
     var diff = Math.abs(slotTop - scrollTop)
+
     expect(slotTop).toBeGreaterThan(0)
     expect(scrollTop).toBeGreaterThan(0)
     expect(diff).toBeLessThan(3)

+ 6 - 5
packages/__tests__/src/view-render/updateSize.js

@@ -1,17 +1,18 @@
+import CalendarWrapper from "../lib/wrappers/CalendarWrapper"
 
 describe('updateSize method', function() {
 
   it('updates size of a previously hidden element', function() {
-    var $el = $('<div style="display:none" />').appendTo('body')
-
-    initCalendar({
+    let $el = $('<div style="display:none" />').appendTo('body')
+    let calendar = initCalendar({
       defaultView: 'dayGridMonth',
       contentHeight: 600
     }, $el)
+    let calendarWrapper = new CalendarWrapper(calendar)
 
     $el.show()
-    currentCalendar.updateSize()
-    expect($('.fc-view-container').outerHeight()).toBeCloseTo(600, 0)
+    calendar.updateSize()
+    expect(calendarWrapper.getViewContainerEl().offsetHeight).toBeCloseTo(600, 0)
 
     $el.remove()
   })