diff --git a/calendar/amd/build/calendar_threemonth.min.js.map b/calendar/amd/build/calendar_threemonth.min.js.map
index cbc75239f2d..ba3216ebda7 100644
--- a/calendar/amd/build/calendar_threemonth.min.js.map
+++ b/calendar/amd/build/calendar_threemonth.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../src/calendar_threemonth.js"],"names":["define","$","Notification","CalendarSelectors","CalendarEvents","Templates","CalendarViewManager","registerCalendarEventListeners","root","body","on","monthChanged","dayChanged","join","e","year","month","courseId","categoryId","queue","next","processRequest","then","fail","exception","newCurrentMonth","find","newParent","closest","calendarPeriods","allMonths","previousMonth","nextMonth","placeHolder","attr","placeHolderContainer","hide","append","requestYear","requestMonth","oldMonth","is","insertBefore","data","insertAfter","Deferred","resolve","refreshMonthContent","slideUpPromise","slideDownPromise","slideUp","remove","slideDown","when","links","miniDayLink","target","day","text","calendarRoot","calendarMain","refreshDayContent","preventDefault","updateUrl","init"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * This module handles display of multiple mini calendars in a view, and\n * movement through them.\n *\n * @module     core_calendar/calendar_threemonth\n * @copyright  2017 Andrew Nicols <andrew@nicols.co.uk>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n    'jquery',\n    'core/notification',\n    'core_calendar/selectors',\n    'core_calendar/events',\n    'core/templates',\n    'core_calendar/view_manager',\n],\nfunction(\n    $,\n    Notification,\n    CalendarSelectors,\n    CalendarEvents,\n    Templates,\n    CalendarViewManager\n) {\n\n    /**\n     * Listen to and handle any calendar events fired by the calendar UI.\n     *\n     * @method registerCalendarEventListeners\n     * @param {object} root The calendar root element\n     */\n    var registerCalendarEventListeners = function(root) {\n        var body = $('body');\n        body.on([CalendarEvents.monthChanged, CalendarEvents.dayChanged].join(' '), function(e, year, month, courseId, categoryId) {\n            // We have to use a queue here because the calling code is decoupled from these listeners.\n            // It's possible for the event to be called multiple times before one call is fully resolved.\n            root.queue(function(next) {\n                return processRequest(e, year, month, courseId, categoryId)\n                .then(function() {\n                    return next();\n                })\n                .fail(Notification.exception)\n                ;\n            });\n        });\n\n        var processRequest = function(e, year, month, courseId, categoryId) {\n            var newCurrentMonth = root.find('[data-year=\"' + year + '\"][data-month=\"' + month + '\"]');\n            var newParent = newCurrentMonth.closest(CalendarSelectors.calendarPeriods.month);\n            var allMonths = root.find(CalendarSelectors.calendarPeriods.month);\n\n            var previousMonth = $(allMonths[0]);\n            var nextMonth = $(allMonths[2]);\n\n            var placeHolder = $('<span>');\n            placeHolder.attr('data-template', 'core_calendar/threemonth_month');\n            placeHolder.attr('data-includenavigation', false);\n            placeHolder.attr('data-mini', true);\n            var placeHolderContainer = $('<div>');\n            placeHolderContainer.hide();\n            placeHolderContainer.append(placeHolder);\n\n            var requestYear;\n            var requestMonth;\n            var oldMonth;\n\n            if (newParent.is(previousMonth)) {\n                // Fetch the new previous month.\n                placeHolderContainer.insertBefore(previousMonth);\n\n                requestYear = previousMonth.data('previousYear');\n                requestMonth = previousMonth.data('previousMonth');\n                oldMonth = nextMonth;\n            } else if (newParent.is(nextMonth)) {\n                // Fetch the new next month.\n                placeHolderContainer.insertAfter(nextMonth);\n                requestYear = nextMonth.data('nextYear');\n                requestMonth = nextMonth.data('nextMonth');\n                oldMonth = previousMonth;\n            } else {\n                return $.Deferred().resolve();\n            }\n\n            return CalendarViewManager.refreshMonthContent(\n                placeHolder,\n                requestYear,\n                requestMonth,\n                courseId,\n                categoryId,\n                placeHolder\n            )\n            .then(function() {\n                var slideUpPromise = $.Deferred();\n                var slideDownPromise = $.Deferred();\n                oldMonth.slideUp('fast', function() {\n                    $(this).remove();\n                    slideUpPromise.resolve();\n                });\n                placeHolderContainer.slideDown('fast', function() {\n                    slideDownPromise.resolve();\n                });\n\n                return $.when(slideUpPromise, slideDownPromise);\n            });\n        };\n\n        // Listen for a click on the day link in the three month block to load the day view.\n        root.on('click', CalendarSelectors.links.miniDayLink, function(e) {\n\n                var miniDayLink = $(e.target);\n                var year = miniDayLink.data('year'),\n                    month = miniDayLink.data('month'),\n                    day = miniDayLink.text(),\n                    courseId = miniDayLink.data('courseid'),\n                    categoryId = miniDayLink.data('categoryid'),\n                    calendarRoot = $('body').find(CalendarSelectors.calendarMain);\n                CalendarViewManager.refreshDayContent(calendarRoot, year, month, day, courseId, categoryId,\n                    calendarRoot.find('[id^=\"calendar-\"][data-template^=\"core_calendar/\"]'), 'core_calendar/calendar_day');\n                e.preventDefault();\n                CalendarViewManager.updateUrl('?view=day');\n        });\n    };\n\n    return {\n        init: function(root) {\n            root = $(root);\n\n            registerCalendarEventListeners(root);\n        }\n    };\n});\n"],"file":"calendar_threemonth.min.js"}
\ No newline at end of file
+{"version":3,"sources":["../src/calendar_threemonth.js"],"names":["define","$","Notification","CalendarSelectors","CalendarEvents","Templates","CalendarViewManager","registerCalendarEventListeners","root","body","on","monthChanged","dayChanged","join","e","year","month","courseId","categoryId","queue","next","processRequest","then","fail","exception","newCurrentMonth","find","newParent","closest","calendarPeriods","allMonths","previousMonth","nextMonth","placeHolder","attr","placeHolderContainer","hide","append","requestYear","requestMonth","oldMonth","is","insertBefore","data","insertAfter","Deferred","resolve","refreshMonthContent","slideUpPromise","slideDownPromise","slideUp","remove","slideDown","when","links","miniDayLink","target","day","text","calendarRoot","calendarMain","refreshDayContent","preventDefault","updateUrl","init"],"mappings":"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","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * This module handles display of multiple mini calendars in a view, and\n * movement through them.\n *\n * @deprecated since 4.0 MDL-72810.\n * @todo       MDL-73117 This will be deleted in Moodle 4.4.\n * @module     core_calendar/calendar_threemonth\n * @copyright  2017 Andrew Nicols <andrew@nicols.co.uk>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine([\n    'jquery',\n    'core/notification',\n    'core_calendar/selectors',\n    'core_calendar/events',\n    'core/templates',\n    'core_calendar/view_manager',\n],\nfunction(\n    $,\n    Notification,\n    CalendarSelectors,\n    CalendarEvents,\n    Templates,\n    CalendarViewManager\n) {\n\n    /**\n     * Listen to and handle any calendar events fired by the calendar UI.\n     *\n     * @method registerCalendarEventListeners\n     * @param {object} root The calendar root element\n     */\n    var registerCalendarEventListeners = function(root) {\n        var body = $('body');\n        body.on([CalendarEvents.monthChanged, CalendarEvents.dayChanged].join(' '), function(e, year, month, courseId, categoryId) {\n            // We have to use a queue here because the calling code is decoupled from these listeners.\n            // It's possible for the event to be called multiple times before one call is fully resolved.\n            root.queue(function(next) {\n                return processRequest(e, year, month, courseId, categoryId)\n                .then(function() {\n                    return next();\n                })\n                .fail(Notification.exception)\n                ;\n            });\n        });\n\n        var processRequest = function(e, year, month, courseId, categoryId) {\n            var newCurrentMonth = root.find('[data-year=\"' + year + '\"][data-month=\"' + month + '\"]');\n            var newParent = newCurrentMonth.closest(CalendarSelectors.calendarPeriods.month);\n            var allMonths = root.find(CalendarSelectors.calendarPeriods.month);\n\n            var previousMonth = $(allMonths[0]);\n            var nextMonth = $(allMonths[2]);\n\n            var placeHolder = $('<span>');\n            placeHolder.attr('data-template', 'core_calendar/threemonth_month');\n            placeHolder.attr('data-includenavigation', false);\n            placeHolder.attr('data-mini', true);\n            var placeHolderContainer = $('<div>');\n            placeHolderContainer.hide();\n            placeHolderContainer.append(placeHolder);\n\n            var requestYear;\n            var requestMonth;\n            var oldMonth;\n\n            if (newParent.is(previousMonth)) {\n                // Fetch the new previous month.\n                placeHolderContainer.insertBefore(previousMonth);\n\n                requestYear = previousMonth.data('previousYear');\n                requestMonth = previousMonth.data('previousMonth');\n                oldMonth = nextMonth;\n            } else if (newParent.is(nextMonth)) {\n                // Fetch the new next month.\n                placeHolderContainer.insertAfter(nextMonth);\n                requestYear = nextMonth.data('nextYear');\n                requestMonth = nextMonth.data('nextMonth');\n                oldMonth = previousMonth;\n            } else {\n                return $.Deferred().resolve();\n            }\n\n            return CalendarViewManager.refreshMonthContent(\n                placeHolder,\n                requestYear,\n                requestMonth,\n                courseId,\n                categoryId,\n                placeHolder\n            )\n            .then(function() {\n                var slideUpPromise = $.Deferred();\n                var slideDownPromise = $.Deferred();\n                oldMonth.slideUp('fast', function() {\n                    $(this).remove();\n                    slideUpPromise.resolve();\n                });\n                placeHolderContainer.slideDown('fast', function() {\n                    slideDownPromise.resolve();\n                });\n\n                return $.when(slideUpPromise, slideDownPromise);\n            });\n        };\n\n        // Listen for a click on the day link in the three month block to load the day view.\n        root.on('click', CalendarSelectors.links.miniDayLink, function(e) {\n\n                var miniDayLink = $(e.target);\n                var year = miniDayLink.data('year'),\n                    month = miniDayLink.data('month'),\n                    day = miniDayLink.text(),\n                    courseId = miniDayLink.data('courseid'),\n                    categoryId = miniDayLink.data('categoryid'),\n                    calendarRoot = $('body').find(CalendarSelectors.calendarMain);\n                CalendarViewManager.refreshDayContent(calendarRoot, year, month, day, courseId, categoryId,\n                    calendarRoot.find('[id^=\"calendar-\"][data-template^=\"core_calendar/\"]'), 'core_calendar/calendar_day');\n                e.preventDefault();\n                CalendarViewManager.updateUrl('?view=day');\n        });\n    };\n\n    return {\n        init: function(root) {\n            root = $(root);\n\n            registerCalendarEventListeners(root);\n        }\n    };\n});\n"],"file":"calendar_threemonth.min.js"}
\ No newline at end of file
diff --git a/calendar/amd/src/calendar_threemonth.js b/calendar/amd/src/calendar_threemonth.js
index e3bed647fa4..576f6c10bc5 100644
--- a/calendar/amd/src/calendar_threemonth.js
+++ b/calendar/amd/src/calendar_threemonth.js
@@ -17,6 +17,8 @@
  * This module handles display of multiple mini calendars in a view, and
  * movement through them.
  *
+ * @deprecated since 4.0 MDL-72810.
+ * @todo       MDL-73117 This will be deleted in Moodle 4.4.
  * @module     core_calendar/calendar_threemonth
  * @copyright  2017 Andrew Nicols <andrew@nicols.co.uk>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
diff --git a/calendar/lib.php b/calendar/lib.php
index e802db4f3b2..e29851a219d 100644
--- a/calendar/lib.php
+++ b/calendar/lib.php
@@ -1307,11 +1307,6 @@ class calendar_information {
             $filters->title = get_string('eventskey', 'calendar');
             $renderer->add_pretend_calendar_block($filters, BLOCK_POS_RIGHT);
         }
-        $block = new block_contents;
-        $block->content = $renderer->fake_block_threemonths($this);
-        $block->footer = '';
-        $block->title = get_string('monthlyview', 'calendar');
-        $renderer->add_pretend_calendar_block($block, BLOCK_POS_RIGHT);
     }
 
     /**
diff --git a/calendar/renderer.php b/calendar/renderer.php
index 5268000dc53..069e132716e 100644
--- a/calendar/renderer.php
+++ b/calendar/renderer.php
@@ -55,10 +55,15 @@ class core_calendar_renderer extends plugin_renderer_base {
      *
      * This includes the previous month, the current month, and the next month
      *
+     * @deprecated since 4.0 MDL-72810.
+     * @todo MDL-73117 This will be deleted in Moodle 4.4.
+     *
      * @param calendar_information $calendar
      * @return string
      */
     public function fake_block_threemonths(calendar_information $calendar) {
+        debugging('This method is no longer used as the three month calendar block has been removed', DEBUG_DEVELOPER);
+
         // Get the calendar type we are using.
         $calendartype = \core_calendar\type_factory::get_calendar_instance();
         $time = $calendartype->timestamp_to_date_array($calendar->time);
diff --git a/calendar/templates/calendar_threemonth.mustache b/calendar/templates/calendar_threemonth.mustache
index b9e41b3d7fb..0da8c3a2180 100644
--- a/calendar/templates/calendar_threemonth.mustache
+++ b/calendar/templates/calendar_threemonth.mustache
@@ -17,6 +17,9 @@
 {{!
     @template calendar/calendar_threemonth
 
+    @deprecated since 4.0 MDL-72810.
+    @todo MDL-73117 This will be deleted in Moodle 4.4.
+
     Calendar view to show three months as a block.
 
     The purpose of this template is to render a set of three months of calendar_mini in a block.
diff --git a/calendar/templates/threemonth_month.mustache b/calendar/templates/threemonth_month.mustache
index 7dddb2fc2c4..f842a830b79 100644
--- a/calendar/templates/threemonth_month.mustache
+++ b/calendar/templates/threemonth_month.mustache
@@ -17,6 +17,9 @@
 {{!
     @template calendar/threemonth_month
 
+    @deprecated since 4.0 MDL-72810.
+    @todo MDL-73117 This will be deleted in Moodle 4.4.
+
     Calendar view to show three months as a block.
 
     The purpose of this template is to render a set of three months of calendar_mini in a block.
diff --git a/calendar/tests/behat/behat_calendar.php b/calendar/tests/behat/behat_calendar.php
index 730cab029e7..71c3cc63c17 100644
--- a/calendar/tests/behat/behat_calendar.php
+++ b/calendar/tests/behat/behat_calendar.php
@@ -89,51 +89,6 @@ class behat_calendar extends behat_base {
         }
     }
 
-    /**
-     * Click a specific day in the calendar.
-     *
-     * @Given /^I click day "(?P<dayofmonth>\d+)" of this month in the calendar$/
-     * @param int $day The day of the current month
-     */
-    public function i_click_day_of_this_month_in_calendar($day) {
-        $summarytitle = userdate(time(), get_string('strftimemonthyear'));
-        // The current month table.
-        $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]";
-
-        // Strings for the class cell match.
-        $cellclasses  = "contains(concat(' ', normalize-space(@class), ' '), ' day ')";
-        $daycontains  = "text()[contains(concat(' ', normalize-space(.), ' '), ' {$day} ')]";
-        $daycell      = "td[{$cellclasses}]";
-        $dayofmonth   = "a[{$daycontains}]";
-
-        $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth;
-        $this->execute("behat_general::wait_until_the_page_is_ready");
-        $this->execute("behat_general::i_click_on", array($xpath, "xpath_element"));
-        $this->execute("behat_general::wait_until_the_page_is_ready");
-
-    }
-
-    /**
-     * Hover over a specific day in the calendar.
-     *
-     * @Given /^I hover over day "(?P<dayofmonth>\d+)" of this month in the calendar$/
-     * @param int $day The day of the current month
-     */
-    public function i_hover_over_day_of_this_month_in_calendar($day) {
-        $summarytitle = userdate(time(), get_string('strftimemonthyear'));
-        // The current month table.
-        $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]";
-
-        // Strings for the class cell match.
-        $cellclasses  = "contains(concat(' ', normalize-space(@class), ' '), ' day ')";
-        $daycontains  = "text()[contains(concat(' ', normalize-space(.), ' '), ' {$day} ')]";
-        $daycell      = "td[{$cellclasses}]";
-        $dayofmonth   = "a[{$daycontains}]";
-
-        $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth;
-        $this->execute("behat_general::i_hover", [$xpath, "xpath_element"]);
-    }
-
     /**
      * Hover over a specific day in the mini-calendar.
      *
diff --git a/calendar/tests/behat/minicalendar.feature b/calendar/tests/behat/minicalendar.feature
index 233ef6b007f..a47da834995 100644
--- a/calendar/tests/behat/minicalendar.feature
+++ b/calendar/tests/behat/minicalendar.feature
@@ -35,23 +35,6 @@ Feature: Open calendar popup
     And I should see "Event 1:1"
     And I should see "Event 1:2"
 
-  @javascript
-  Scenario: I view a day event then another day event
-    Given I follow "Full calendar"
-    And I create a calendar event:
-      | Type of event     | site |
-      | Event title       | Event 3:1 |
-      | timestart[day]    | 3  |
-    And I create a calendar event:
-      | Type of event     | site |
-      | Event title       | Event 4:1 |
-      | timestart[day]    | 4  |
-    And I reload the page
-    When I click day "3" of this month in the calendar
-    Then I should see "Event 3:1" in the ".eventlist" "css_element"
-    And I click day "4" of this month in the calendar
-    And I should see "Event 4:1" in the ".eventlist" "css_element"
-
   @javascript
   Scenario: I view calendar details for today
     Given I follow "Full calendar"
diff --git a/calendar/upgrade.txt b/calendar/upgrade.txt
index 303e129858c..a775ecc70d8 100644
--- a/calendar/upgrade.txt
+++ b/calendar/upgrade.txt
@@ -12,7 +12,11 @@ information provided here is intended especially for developers.
   - calendar_import_icalendar_events()
 * The following has been removed after being deprecated in 3.8
   * CALENDAR_EVENT_GLOBAL
-
+* The following have been deprecated because the three-month pseudo block has been removed:
+  - fake_block_threemonths() renderer method.
+  - calendar_threemonth.js.
+  - calendar_threemonth and threemonth_month templates.
+  - Behat step definitions i_hover_over_day_of_this_month_in_calendar and i_click_day_of_this_month_in_calendar.
 
 === 3.10 ===
 * The core_calendar\local\event\value_objects\times_interface class now has new method get_usermidnight_time() which
diff --git a/lang/en/calendar.php b/lang/en/calendar.php
index 10b89b82c4e..d39b56414dd 100644
--- a/lang/en/calendar.php
+++ b/lang/en/calendar.php
@@ -183,7 +183,6 @@ $string['manyevents'] = '{$a} events';
 $string['mon'] = 'Mon';
 $string['monday'] = 'Monday';
 $string['monthly'] = 'Monthly';
-$string['monthlyview'] = 'Monthly view';
 $string['monthnext'] = 'Next month';
 $string['monthprev'] = 'Previous month';
 $string['monththis'] = 'This month';
@@ -286,6 +285,7 @@ $string['yoursubscriptions'] = 'Imported calendars';
 // Deprecated since Moodle 4.0.
 $string['calendarurl'] = 'Calendar URL: {$a}';
 $string['importfrominstructions'] = 'Please provide either a URL to a remote calendar, or upload a file.';
+$string['monthlyview'] = 'Monthly view';
 
 // Deprecated since Moodle 3.8.
 $string['global'] = 'Global';
diff --git a/lang/en/deprecated.txt b/lang/en/deprecated.txt
index d38721c0e5b..a5495786465 100644
--- a/lang/en/deprecated.txt
+++ b/lang/en/deprecated.txt
@@ -163,3 +163,4 @@ mediapluginswf,core_admin
 mediapluginswfnote,core_admin
 createuserandpass,core
 supplyinfo,core
+monthlyview,core_calendar
diff --git a/lib/tests/behat/behat_deprecated.php b/lib/tests/behat/behat_deprecated.php
index f8c3faec41f..a5f16ce2d27 100644
--- a/lib/tests/behat/behat_deprecated.php
+++ b/lib/tests/behat/behat_deprecated.php
@@ -81,4 +81,56 @@ class behat_deprecated extends behat_base {
         throw new Exception($message);
     }
 
+    /**
+     * Hover over a specific day in the calendar.
+     *
+     * @Given /^I hover over day "(?P<dayofmonth>\d+)" of this month in the calendar$/
+     * @param int $day The day of the current month
+     *
+     * @deprecated since 4.0 MDL-72810. This tested the three-month calendar pseudo block, which has been removed.
+     * @todo MDL-73117 This will be deleted in Moodle 4.4.
+     */
+    public function i_hover_over_day_of_this_month_in_calendar($day) {
+        $this->deprecated_message('Check information in the course or timeline calendar blocks or full calendar, as appropriate.');
+
+        $summarytitle = userdate(time(), get_string('strftimemonthyear'));
+        // The current month table.
+        $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]";
+
+        // Strings for the class cell match.
+        $cellclasses  = "contains(concat(' ', normalize-space(@class), ' '), ' day ')";
+        $daycontains  = "text()[contains(concat(' ', normalize-space(.), ' '), ' {$day} ')]";
+        $daycell      = "td[{$cellclasses}]";
+        $dayofmonth   = "a[{$daycontains}]";
+
+        $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth;
+        $this->execute("behat_general::i_hover", [$xpath, "xpath_element"]);
+    }
+
+    /**
+     * Click a specific day in the calendar.
+     *
+     * @Given /^I click day "(?P<dayofmonth>\d+)" of this month in the calendar$/
+     * @param int $day The day of the current month
+     *
+     * @deprecated since 4.0 MDL-72810. This tested the three-month calendar pseudo block, which has been removed.
+     * @todo MDL-73117 This will be deleted in Moodle 4.4.
+     */
+    public function i_click_day_of_this_month_in_calendar($day) {
+        $this->deprecated_message('Check information in the course or timeline calendar blocks or full calendar, as appropriate.');
+
+        // The current month table.
+        $currentmonth = "table[descendant::*[self::caption[contains(concat(' ', normalize-space(.), ' '), ' {$summarytitle} ')]]]";
+
+        // Strings for the class cell match.
+        $cellclasses  = "contains(concat(' ', normalize-space(@class), ' '), ' day ')";
+        $daycontains  = "text()[contains(concat(' ', normalize-space(.), ' '), ' {$day} ')]";
+        $daycell      = "td[{$cellclasses}]";
+        $dayofmonth   = "a[{$daycontains}]";
+
+        $xpath = '//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth;
+        $this->execute("behat_general::wait_until_the_page_is_ready");
+        $this->execute("behat_general::i_click_on", array($xpath, "xpath_element"));
+        $this->execute("behat_general::wait_until_the_page_is_ready");
+    }
 }
diff --git a/mod/assign/tests/behat/set_availability.feature b/mod/assign/tests/behat/set_availability.feature
index 7e7f90751ae..64f98373701 100644
--- a/mod/assign/tests/behat/set_availability.feature
+++ b/mod/assign/tests/behat/set_availability.feature
@@ -56,9 +56,8 @@ Feature: Set availability dates for an assignment
     And I log out
 
     And I am on the "C1" Course page logged in as student1
-    And I follow "Full calendar"
-    When I hover over day "2" of this month in the calendar
-    Then I should see "C1: Assignment name is due"
+    When I hover over day "2" of this month in the mini-calendar block
+    Then I should see "Assignment name is due"
 
   @_file_upload
   Scenario: Student can submit an assignment before the due date