diff --git a/django/contrib/admin/static/admin/js/actions.js b/django/contrib/admin/static/admin/js/actions.js
index 7aca5b4fe8..58f572f252 100644
--- a/django/contrib/admin/static/admin/js/actions.js
+++ b/django/contrib/admin/static/admin/js/actions.js
@@ -16,6 +16,8 @@
 		},
 		updateCounter = function() {
 			var sel = $(actionCheckboxes).filter(":checked").length;
+			// _actions_icnt is defined in the generated HTML
+			// and contains the total amount of objects in the queryset
 			$(options.counterContainer).html(interpolate(
 			ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
 				sel: sel,
diff --git a/django/contrib/admin/static/admin/js/actions.min.js b/django/contrib/admin/static/admin/js/actions.min.js
index b43ab145dd..0dd6683fb3 100644
--- a/django/contrib/admin/static/admin/js/actions.min.js
+++ b/django/contrib/admin/static/admin/js/actions.min.js
@@ -1,4 +1,4 @@
-(function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:void 0},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide();
+(function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide();
 a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);
 h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,
 d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});
diff --git a/tests/admin_changelist/admin.py b/tests/admin_changelist/admin.py
index 42b8c959af..b2bd578e80 100644
--- a/tests/admin_changelist/admin.py
+++ b/tests/admin_changelist/admin.py
@@ -1,11 +1,15 @@
 from django.contrib import admin
 from django.core.paginator import Paginator
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.auth.models import User
 
 from .models import Event, Child, Parent, Swallow
 
 
 site = admin.AdminSite(name="admin")
 
+site.register(User, UserAdmin)
+
 
 class CustomPaginator(Paginator):
     def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True):
diff --git a/tests/admin_changelist/fixtures/users.json b/tests/admin_changelist/fixtures/users.json
new file mode 100644
index 0000000000..72d86d70ad
--- /dev/null
+++ b/tests/admin_changelist/fixtures/users.json
@@ -0,0 +1,20 @@
+[
+  {
+    "pk": 100,
+    "model": "auth.user",
+    "fields": {
+      "username": "super",
+      "first_name": "Super",
+      "last_name": "User",
+      "is_active": true,
+      "is_superuser": true,
+      "is_staff": true,
+      "last_login": "2007-05-30 13:20:10",
+      "groups": [],
+      "user_permissions": [],
+      "password": "sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158",
+      "email": "super@example.com",
+      "date_joined": "2007-05-30 13:20:10"
+    }
+  }
+]
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py
index 4819dfe4d9..ca889f0648 100644
--- a/tests/admin_changelist/tests.py
+++ b/tests/admin_changelist/tests.py
@@ -6,10 +6,11 @@ from django.contrib import admin
 from django.contrib.admin.options import IncorrectLookupParameters
 from django.contrib.admin.templatetags.admin_list import pagination
 from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR
+from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
 from django.contrib.auth.models import User
 from django.core.urlresolvers import reverse
 from django.template import Context, Template
-from django.test import TestCase
+from django.test import TestCase, override_settings
 from django.test.client import RequestFactory
 from django.utils import formats
 from django.utils import six
@@ -661,3 +662,46 @@ class AdminLogNodeTestCase(TestCase):
         # Rendering should be u'' since this templatetag just logs,
         # it doesn't render any string.
         self.assertEqual(template.render(context), '')
+
+
+@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
+class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
+
+    available_apps = ['admin_changelist'] + AdminSeleniumWebDriverTestCase.available_apps
+    fixtures = ['users.json']
+    urls = "admin_changelist.urls"
+    webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
+
+    def test_add_row_selection(self):
+        """
+        Ensure that the status line for selected rows gets updated correcly (#22038)
+        """
+        self.admin_login(username='super', password='secret')
+        self.selenium.get('%s%s' % (self.live_server_url,
+                                    '/admin/auth/user/'))
+
+        form_id = '#changelist-form'
+
+        # Test amount of rows in the Changelist
+        rows = self.selenium.find_elements_by_css_selector(
+            '%s #result_list tbody tr' % form_id)
+        self.assertEqual(len(rows), 1)
+
+        # Test current selection
+        selection_indicator = self.selenium.find_element_by_css_selector(
+            '%s .action-counter' % form_id)
+        self.assertEqual(selection_indicator.text, "0 of 1 selected")
+
+        # Select a row and check again
+        row_selector = self.selenium.find_element_by_css_selector(
+            '%s #result_list tbody tr:first-child .action-select' % form_id)
+        row_selector.click()
+        self.assertEqual(selection_indicator.text, "1 of 1 selected")
+
+
+class SeleniumChromeTests(SeleniumFirefoxTests):
+    webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver'
+
+
+class SeleniumIETests(SeleniumFirefoxTests):
+    webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'