diff --git a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
index 58aba45..b1db6d1 100644
--- a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
+++ b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
@@ -33,6 +33,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/modules/book/src/Tests/BookTest.php b/core/modules/book/src/Tests/BookTest.php
index cdd61c6..679af4c 100644
--- a/core/modules/book/src/Tests/BookTest.php
+++ b/core/modules/book/src/Tests/BookTest.php
@@ -741,8 +741,8 @@ public function testBookNavigationBlockOnUnpublishedBook() {
     $this->drupalPlaceBlock('book_navigation', ['block_mode' => 'book pages']);
 
     // Unpublish book node.
-    $edit = [];
-    $this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save and unpublish'));
+    $edit = array('status[value]' => FALSE);
+    $this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save'));
 
     // Test node page.
     $this->drupalGet('node/' . $this->book->id());
diff --git a/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php b/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
index 504b3ba..e208c71 100644
--- a/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
+++ b/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
@@ -86,14 +86,14 @@ public function testCommentStatusFieldAccessStatus() {
     $assert->fieldNotExists('comment[0][status]');
     $this->submitForm([
       'title[0][value]' => 'Node 1',
-    ], t('Save and publish'));
+    ], t('Save'));
     $assert->fieldExists('subject[0][value]');
     $this->drupalLogin($this->commentAdmin);
     $this->drupalGet('node/add/article');
     $assert->fieldExists('comment[0][status]');
     $this->submitForm([
       'title[0][value]' => 'Node 2',
-    ], t('Save and publish'));
+    ], t('Save'));
     $assert->fieldExists('subject[0][value]');
   }
 
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
index fe36336..0db3398 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
@@ -63,7 +63,7 @@ public function testCreatingContent() {
     // Create a new node.
     $this->drupalPostForm('node/add/moderated_content', [
       'title[0][value]' => 'non-moderated content',
-    ], t('Save and publish'));
+    ], t('Save'));
 
     $node = $this->getNodeByTitle('non-moderated content');
     if (!$node) {
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
index 099b4dc..5c494da 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
@@ -19,10 +19,10 @@ public function testNotModerated() {
     $this->assertText('The content type Not moderated has been added.');
     $this->grantUserPermissionToCreateContentOfType($this->adminUser, 'not_moderated');
     $this->drupalGet('node/add/not_moderated');
-    $this->assertRaw('Save as unpublished');
+    $this->assertRaw('Save');
     $this->drupalPostForm(NULL, [
       'title[0][value]' => 'Test',
-    ], t('Save and publish'));
+    ], t('Save'));
     $this->assertText('Not moderated Test has been created.');
   }
 
@@ -39,7 +39,7 @@ public function testEnablingOnExistingContent() {
     $this->drupalGet('node/add/not_moderated');
     $this->drupalPostForm(NULL, [
       'title[0][value]' => 'Test',
-    ], t('Save and publish'));
+    ], t('Save'));
     $this->assertText('Not moderated Test has been created.');
 
     // Now enable moderation state, ensuring all the expected links and tabs are
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php b/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
index fea0e14..4280da0 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
@@ -73,12 +73,12 @@ public function testLanguageChange() {
     $edit = [
       'title[0][value]' => 'english_title',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Create a translation in French.
     $this->clickLink('Translate');
     $this->clickLink('Add');
-    $this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, [], t('Save (this translation)'));
     $this->clickLink('Translate');
 
     // Edit English translation.
@@ -90,7 +90,7 @@ public function testLanguageChange() {
       'files[field_image_field_0]' => $images->uri,
     ];
     $this->drupalPostForm(NULL, $edit, t('Upload'));
-    $this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save (this translation)'));
 
     // Check that the translation languages are correct.
     $node = $this->getNodeByTitle('english_title');
@@ -109,13 +109,13 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
       'title[0][value]' => 'english_title',
       'test_field_only_en_fr' => 'node created',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->assertEqual('node created', \Drupal::state()->get('test_field_only_en_fr'));
 
     // Create a translation in French.
     $this->clickLink('Translate');
     $this->clickLink('Add');
-    $this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, [], t('Save (this translation)'));
     $this->clickLink('Translate');
 
     // Edit English translation.
@@ -137,7 +137,7 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
       'langcode[0][value]' => 'en',
       'field_image_field[0][alt]' => 'alternative_text'
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
 
     // Check that the translation languages are correct.
     $node = $this->getNodeByTitle('english_title');
diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceXSSTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceXSSTest.php
index f72312f..bac6815 100644
--- a/core/modules/field/src/Tests/EntityReference/EntityReferenceXSSTest.php
+++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceXSSTest.php
@@ -61,7 +61,7 @@ public function testEntityReferenceXSS() {
       'title[0][value]' => $this->randomString(),
       'entity_reference_test' => $referenced_node->id()
     ];
-    $this->drupalPostForm(NULL, $edit, 'Save and publish');
+    $this->drupalPostForm(NULL, $edit, 'Save');
     $this->assertEscaped($referenced_node->getTitle());
 
     // Test the options_buttons type.
diff --git a/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php b/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
index 2286473..b9c6dcd 100644
--- a/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
+++ b/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
@@ -138,7 +138,7 @@ protected function doTestNodeWithFileWithoutTitle() {
       $label = 'Save';
     }
     else {
-      $label = 'Save and publish';
+      $label = 'Save';
     }
     $this->drupalPostForm(NULL, $edit, $label);
     $this->assertResponse(200);
diff --git a/core/modules/file/src/Tests/FileFieldDisplayTest.php b/core/modules/file/src/Tests/FileFieldDisplayTest.php
index b25b514..4b47b29 100644
--- a/core/modules/file/src/Tests/FileFieldDisplayTest.php
+++ b/core/modules/file/src/Tests/FileFieldDisplayTest.php
@@ -77,7 +77,7 @@ function testNodeDisplay() {
 
     // Turn the "display" option off and check that the file is no longer displayed.
     $edit = array($field_name . '[0][display]' => FALSE);
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
 
     $this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
 
@@ -87,7 +87,7 @@ function testNodeDisplay() {
       $field_name . '[0][description]' => $description,
       $field_name . '[0][display]' => TRUE,
     );
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $this->assertText($description);
 
     // Ensure the filename in the link's title attribute is escaped.
@@ -167,7 +167,7 @@ function testDescToggle() {
       'title[0][value]' => $title,
       'files[field_' . $field_name . '_0]' => drupal_realpath($file->uri),
     );
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($title);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertText(t('The description may be used as the label of the link to the file.'));
diff --git a/core/modules/file/src/Tests/FileFieldRevisionTest.php b/core/modules/file/src/Tests/FileFieldRevisionTest.php
index f5d00c7..83df8d3 100644
--- a/core/modules/file/src/Tests/FileFieldRevisionTest.php
+++ b/core/modules/file/src/Tests/FileFieldRevisionTest.php
@@ -63,7 +63,7 @@ function testRevisions() {
 
     // Save a new version of the node without any changes.
     // Check that the file is still the same as the previous revision.
-    $this->drupalPostForm('node/' . $nid . '/edit', array('revision' => '1'), t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', array('revision' => '1'), t('Save'));
     $node_storage->resetCache(array($nid));
     $node = $node_storage->load($nid);
     $node_file_r3 = File::load($node->{$field_name}->target_id);
diff --git a/core/modules/file/src/Tests/FileFieldTestBase.php b/core/modules/file/src/Tests/FileFieldTestBase.php
index 307eb4d..f634787 100644
--- a/core/modules/file/src/Tests/FileFieldTestBase.php
+++ b/core/modules/file/src/Tests/FileFieldTestBase.php
@@ -224,7 +224,7 @@ function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_revision
         $edit[$name][] = $file_path;
       }
     }
-    $this->drupalPostForm("node/$nid/edit", $edit, t('Save and keep published'));
+    $this->drupalPostForm("node/$nid/edit", $edit, t('Save'));
 
     return $nid;
   }
@@ -240,7 +240,7 @@ function removeNodeFile($nid, $new_revision = TRUE) {
     );
 
     $this->drupalPostForm('node/' . $nid . '/edit', array(), t('Remove'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
   }
 
   /**
@@ -253,7 +253,7 @@ function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE) {
     );
 
     $this->drupalPostForm('node/' . $nid . '/edit', array(), t('Remove'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
   }
 
   /**
diff --git a/core/modules/file/src/Tests/FileFieldValidateTest.php b/core/modules/file/src/Tests/FileFieldValidateTest.php
index 9d43060..942bad7 100644
--- a/core/modules/file/src/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/src/Tests/FileFieldValidateTest.php
@@ -29,7 +29,7 @@ function testRequired() {
     // Try to post a new node without uploading a file.
     $edit = array();
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $this->assertRaw(t('@title field is required.', array('@title' => $field->getLabel())), 'Node save failed when required file field was empty.');
 
     // Create a new node with the uploaded file.
@@ -50,7 +50,7 @@ function testRequired() {
     // Try to post a new node without uploading a file in the multivalue field.
     $edit = array();
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $this->assertRaw(t('@title field is required.', array('@title' => $field->getLabel())), 'Node save failed when required multiple value file field was empty.');
 
     // Create a new node with the uploaded file into the multivalue field.
diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php
index 414c86b..0a53b85 100644
--- a/core/modules/file/src/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php
@@ -121,7 +121,7 @@ function testSingleValuedWidget() {
       $this->assertTrue(isset($label[0]), 'Label for upload found.');
 
       // Save the node and ensure it does not have the file.
-      $this->drupalPostForm(NULL, array(), t('Save and keep published'));
+      $this->drupalPostForm(NULL, array(), t('Save'));
       $node_storage->resetCache(array($nid));
       $node = $node_storage->load($nid);
       $this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
@@ -238,7 +238,7 @@ function testMultiValuedWidget() {
       $this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', array('%type' => $type)));
 
       // Save the node and ensure it does not have any files.
-      $this->drupalPostForm(NULL, array('title[0][value]' => $this->randomMachineName()), t('Save and publish'));
+      $this->drupalPostForm(NULL, array('title[0][value]' => $this->randomMachineName()), t('Save'));
       $matches = array();
       preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
       $nid = $matches[1];
@@ -368,7 +368,7 @@ function testPrivateFileComment() {
     $edit = array(
       'title[0][value]' => $this->randomMachineName(),
     );
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
 
     // Add a comment with a file.
@@ -402,7 +402,8 @@ function testPrivateFileComment() {
 
     // Unpublishes node.
     $this->drupalLogin($this->adminUser);
-    $this->drupalPostForm('node/' . $node->id() . '/edit', array(), t('Save and unpublish'));
+    $edit = array('status[value]' => FALSE);
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Ensures normal user can no longer download the file.
     $this->drupalLogin($user);
diff --git a/core/modules/file/src/Tests/FilePrivateTest.php b/core/modules/file/src/Tests/FilePrivateTest.php
index 2705ef2..fe6294d 100644
--- a/core/modules/file/src/Tests/FilePrivateTest.php
+++ b/core/modules/file/src/Tests/FilePrivateTest.php
@@ -72,10 +72,10 @@ function testPrivateFile() {
     // Attempt to reuse the file when editing a node.
     $edit = array();
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $edit[$field_name . '[0][fids]'] = $node_file->id();
-    $this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save'));
     // Make sure the form submit failed - we stayed on the edit form.
     $this->assertUrl('node/' . $new_node->id() . '/edit');
     // Check that we got the expected constraint form error.
@@ -86,7 +86,7 @@ function testPrivateFile() {
     $edit = array();
     $edit['title[0][value]'] = $this->randomMachineName();
     $edit[$field_name . '[0][fids]'] = $node_file->id();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue(empty($new_node), 'Node was not created.');
     $this->assertUrl('node/add/' . $type_name);
diff --git a/core/modules/filter/src/Tests/FilterHooksTest.php b/core/modules/filter/src/Tests/FilterHooksTest.php
index 5353ccb..c9e95ce 100644
--- a/core/modules/filter/src/Tests/FilterHooksTest.php
+++ b/core/modules/filter/src/Tests/FilterHooksTest.php
@@ -60,7 +60,7 @@ function testFilterHooks() {
     $edit['title[0][value]'] = $title;
     $edit['body[0][value]'] = $this->randomMachineName(32);
     $edit['body[0][format]'] = $format_id;
-    $this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save and publish'));
+    $this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save'));
     $this->assertText(t('@type @title has been created.', array('@type' => $type_name, '@title' => $title)));
 
     // Disable the text format.
diff --git a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
index 6773d32..965a691 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
@@ -42,6 +42,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/modules/forum/src/Tests/ForumBlockTest.php b/core/modules/forum/src/Tests/ForumBlockTest.php
index 1bcc9bc..39815c1 100644
--- a/core/modules/forum/src/Tests/ForumBlockTest.php
+++ b/core/modules/forum/src/Tests/ForumBlockTest.php
@@ -170,7 +170,7 @@ protected function createForumTopics($count = 5) {
       );
 
       // Create the forum topic, preselecting the forum ID via a URL parameter.
-      $this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), array('query' => array('forum_id' => 1)));
+      $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => 1)));
       $topics[] = $title;
     }
 
diff --git a/core/modules/forum/src/Tests/ForumIndexTest.php b/core/modules/forum/src/Tests/ForumIndexTest.php
index 8ead34f..6131609 100644
--- a/core/modules/forum/src/Tests/ForumIndexTest.php
+++ b/core/modules/forum/src/Tests/ForumIndexTest.php
@@ -44,7 +44,7 @@ function testForumIndexStatus() {
     $this->drupalGet("forum/$tid");
     $this->clickLink(t('Add new @node_type', array('@node_type' => 'Forum topic')));
     $this->assertUrl('node/add/forum', array('query' => array('forum_id' => $tid)));
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Check that the node exists in the database.
     $node = $this->drupalGetNodeByTitle($title);
@@ -71,7 +71,8 @@ function testForumIndexStatus() {
 
 
     // Unpublish the node.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', array(), t('Save and unpublish'));
+    $edit = array('status[value]' => FALSE);
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->drupalGet('node/' . $node->id());
     $this->assertText(t('Access denied'), 'Unpublished node is no longer accessible.');
 
diff --git a/core/modules/image/src/Tests/ImageFieldDisplayTest.php b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
index f3ce858..36d6964 100644
--- a/core/modules/image/src/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
@@ -282,7 +282,7 @@ function testImageFieldSettings() {
       $field_name . '[0][alt]' => $image['#alt'],
       $field_name . '[0][title]' => $image['#title'],
     );
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Image displayed using user supplied alt and title attributes.');
 
@@ -292,7 +292,7 @@ function testImageFieldSettings() {
       $field_name . '[0][alt]' => $this->randomMachineName($test_size),
       $field_name . '[0][title]' => $this->randomMachineName($test_size),
     );
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $schema = $field->getFieldStorageDefinition()->getSchema();
     $this->assertRaw(t('Alternative text cannot be longer than %max characters but is currently %length characters long.', array(
       '%max' => $schema['columns']['alt']['length'],
@@ -314,9 +314,9 @@ function testImageFieldSettings() {
     $edit = array(
       'files[' . $field_name . '_1][]' => drupal_realpath($test_image->uri),
     );
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     // Add the required alt text.
-    $this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save and keep published'));
+    $this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save'));
     $this->assertText(format_string('Article @title has been updated.', array('@title' => $node->getTitle())));
 
     // Assert ImageWidget::process() calls FieldWidget::process().
diff --git a/core/modules/image/src/Tests/ImageFieldTestBase.php b/core/modules/image/src/Tests/ImageFieldTestBase.php
index bb976f9..e9e82cc 100644
--- a/core/modules/image/src/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/src/Tests/ImageFieldTestBase.php
@@ -87,10 +87,10 @@ function uploadNodeImage($image, $field_name, $type, $alt = '') {
       'title[0][value]' => $this->randomMachineName(),
     );
     $edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
-    $this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type, $edit, t('Save'));
     if ($alt) {
       // Add alt text.
-      $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save and publish'));
+      $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save'));
     }
 
     // Retrieve ID of the newly created node from the current URL.
diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php
index 5f0bf21..df45f94 100644
--- a/core/modules/image/src/Tests/ImageFieldValidateTest.php
+++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
@@ -119,7 +119,7 @@ function testRequiredAttributes() {
     $edit = array(
       'title[0][value]' => $this->randomMachineName(),
     );
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     $this->assertNoText(t('Alternative text field is required.'));
     $this->assertNoText(t('Title field is required.'));
@@ -132,7 +132,7 @@ function testRequiredAttributes() {
     $edit = array(
       'title[0][value]' => $this->randomMachineName(),
     );
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     $this->assertNoText(t('Alternative text field is required.'));
     $this->assertNoText(t('Title field is required.'));
diff --git a/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php b/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
index 3ee24b4..37fa7ff 100644
--- a/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
+++ b/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
@@ -87,7 +87,7 @@ public function testFragmentLink() {
     // Only enter a title in the node add form and leave the body field empty.
     $edit = ['edit-title-0-value' => 'Test inline form error with CKEditor'];
 
-    $this->submitForm($edit, 'Save and publish');
+    $this->submitForm($edit, 'Save');
 
     // Add a bottom margin to the title field to be sure the body field is not
     // visible. PhantomJS runs with a resolution of 1024x768px.
diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module
index bb3ec23..1bad808 100644
--- a/core/modules/menu_ui/menu_ui.module
+++ b/core/modules/menu_ui/menu_ui.module
@@ -352,11 +352,7 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) {
     '#description' => t('Menu links with lower weights are displayed before links with higher weights.'),
   );
 
-  foreach (array_keys($form['actions']) as $action) {
-    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
-      $form['actions'][$action]['#submit'][] = 'menu_ui_form_node_form_submit';
-    }
-  }
+  $form['actions']['submit']['#submit'][] = 'menu_ui_form_node_form_submit';
 }
 
 /**
diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
index 3fc8423..c74af29 100644
--- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
@@ -13,7 +13,6 @@
  * @group menu_ui
  */
 class MenuNodeTest extends WebTestBase {
-
   /**
    * An editor user.
    *
@@ -133,37 +132,6 @@ function testMenuNodeFormWidget() {
     // Assert that there is no link for the node.
     $this->drupalGet('test-page');
     $this->assertNoLink($node_title);
-
-    // Use not only the save button, but also the two special buttons:
-    // 'Save and publish' as well as 'Save and keep published'.
-    // These buttons just appear for 'administer nodes' users.
-    $admin_user = $this->drupalCreateUser([
-      'access administration pages',
-      'administer content types',
-      'administer nodes',
-      'administer menu',
-      'create page content',
-      'edit any page content',
-    ]);
-    $this->drupalLogin($admin_user);
-    foreach (['Save and unpublish' => FALSE, 'Save and keep unpublished' => FALSE, 'Save and publish' => TRUE, 'Save and keep published' => TRUE] as $submit => $visible) {
-      $edit = [
-        'menu[enabled]' => 1,
-        'menu[title]' => $node_title,
-      ];
-      $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, $submit);
-      // Assert that the link exists.
-      $this->drupalGet('test-page');
-      if ($visible) {
-        $this->assertLink($node_title, 0, 'Found a menu link after submitted with ' . $submit);
-      }
-      else {
-        $this->assertNoLink($node_title, 'Found no menu link after submitted with ' . $submit);
-      }
-    }
-
-    // Log back in as normal user.
-    $this->drupalLogin($this->editor);
     // Edit the node and create a menu link.
     $edit = array(
       'menu[enabled]' => 1,
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 0582459..acb8291 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\user\RoleInterface;
 
@@ -253,5 +254,28 @@ function node_update_8301() {
 }
 
 /**
+ * Load all form displays for nodes, add status with these settings, save.
+ */
+function node_update_8302() {
+  $query = \Drupal::entityQuery('entity_form_display')
+    ->condition('targetEntityType', 'node');
+  $ids = $query->execute();
+  $form_displays = EntityFormDisplay::loadMultiple($ids);
+
+  // Assign status settings for each 'node' target entity types with 'default'
+  // form mode.
+  foreach ($form_displays as $id => $form_display) {
+    $form_display->setComponent('status', [
+      'type' => 'boolean_checkbox',
+      'settings' => [
+        'display_label' => TRUE,
+      ],
+    ])
+      ->save();
+  }
+}
+
+
+/**
  * @} End of "addtogroup updates-8.3.x".
  */
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index 0edb58f..e390c97 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -400,6 +400,16 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ))
       ->setDisplayConfigurable('form', TRUE);
 
+    $fields['status']->setLabel(t('Published'))
+      ->setDisplayOptions('form', array(
+        'type' => 'boolean_checkbox',
+        'settings' => array(
+          'display_label' => TRUE,
+        ),
+        'weight' => 120,
+      ))
+      ->setDisplayConfigurable('form', TRUE);
+
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(t('Authored on'))
       ->setDescription(t('The time that the node was created.'))
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index bb58377..4689a80 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -145,35 +145,23 @@ public function form(array $form, FormStateInterface $form_state) {
       $form['sticky']['#group'] = 'options';
     }
 
+    $form['published'] = [
+      '#type' => 'fieldset',
+      '#title' => 'Published status',
+      '#attributes' => ['class' => ['published-status']],
+    ];
+
+    if (isset($form['status'])) {
+      $form['status']['#group'] = 'published';
+      $form['published']['#weight'] = $form['status']['#weight'];
+    }
+
     $form['#attached']['library'][] = 'node/form';
 
-    $form['#entity_builders']['update_status'] = '::updateStatus';
-
     return $form;
   }
 
   /**
-   * Entity builder updating the node status with the submitted value.
-   *
-   * @param string $entity_type_id
-   *   The entity type identifier.
-   * @param \Drupal\node\NodeInterface $node
-   *   The node updated with the submitted values.
-   * @param array $form
-   *   The complete form array.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @see \Drupal\node\NodeForm::form()
-   */
-  function updateStatus($entity_type_id, NodeInterface $node, array $form, FormStateInterface $form_state) {
-    $element = $form_state->getTriggeringElement();
-    if (isset($element['#published_status'])) {
-      $node->setPublished($element['#published_status']);
-    }
-  }
-
-  /**
    * {@inheritdoc}
    */
   protected function actions(array $form, FormStateInterface $form_state) {
@@ -183,59 +171,6 @@ protected function actions(array $form, FormStateInterface $form_state) {
 
     $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
 
-    // If saving is an option, privileged users get dedicated form submit
-    // buttons to adjust the publishing status while saving in one go.
-    // @todo This adjustment makes it close to impossible for contributed
-    //   modules to integrate with "the Save operation" of this form. Modules
-    //   need a way to plug themselves into 1) the ::submit() step, and
-    //   2) the ::save() step, both decoupled from the pressed form button.
-    if ($element['submit']['#access'] && \Drupal::currentUser()->hasPermission('administer nodes')) {
-      // isNew | prev status » default   & publish label             & unpublish label
-      // 1     | 1           » publish   & Save and publish          & Save as unpublished
-      // 1     | 0           » unpublish & Save and publish          & Save as unpublished
-      // 0     | 1           » publish   & Save and keep published   & Save and unpublish
-      // 0     | 0           » unpublish & Save and keep unpublished & Save and publish
-
-      // Add a "Publish" button.
-      $element['publish'] = $element['submit'];
-      // If the "Publish" button is clicked, we want to update the status to "published".
-      $element['publish']['#published_status'] = TRUE;
-      $element['publish']['#dropbutton'] = 'save';
-      if ($node->isNew()) {
-        $element['publish']['#value'] = t('Save and publish');
-      }
-      else {
-        $element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish');
-      }
-      $element['publish']['#weight'] = 0;
-
-      // Add a "Unpublish" button.
-      $element['unpublish'] = $element['submit'];
-      // If the "Unpublish" button is clicked, we want to update the status to "unpublished".
-      $element['unpublish']['#published_status'] = FALSE;
-      $element['unpublish']['#dropbutton'] = 'save';
-      if ($node->isNew()) {
-        $element['unpublish']['#value'] = t('Save as unpublished');
-      }
-      else {
-        $element['unpublish']['#value'] = !$node->isPublished() ? t('Save and keep unpublished') : t('Save and unpublish');
-      }
-      $element['unpublish']['#weight'] = 10;
-
-      // If already published, the 'publish' button is primary.
-      if ($node->isPublished()) {
-        unset($element['unpublish']['#button_type']);
-      }
-      // Otherwise, the 'unpublish' button is primary and should come first.
-      else {
-        unset($element['publish']['#button_type']);
-        $element['unpublish']['#weight'] = -10;
-      }
-
-      // Remove the "Save" button.
-      $element['submit']['#access'] = FALSE;
-    }
-
     $element['preview'] = array(
       '#type' => 'submit',
       '#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')),
diff --git a/core/modules/node/src/Tests/NodeEditFormTest.php b/core/modules/node/src/Tests/NodeEditFormTest.php
index bef0252..c005e02 100644
--- a/core/modules/node/src/Tests/NodeEditFormTest.php
+++ b/core/modules/node/src/Tests/NodeEditFormTest.php
@@ -98,7 +98,7 @@ public function testNodeEdit() {
     $edit['title[0][value]'] = $this->randomMachineName(8);
     $edit[$body_key] = $this->randomMachineName(16);
     $edit['revision'] = TRUE;
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Ensure that the node revision has been created.
     $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE);
@@ -124,12 +124,21 @@ public function testNodeEdit() {
     $edit['created[0][value][date]'] = $this->randomMachineName(8);
     // Get the current amount of open details elements.
     $open_details_elements = count($this->cssSelect('details[open="open"]'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     // The node author details must be open.
     $this->assertRaw('<details class="node-form-author js-form-wrapper form-wrapper" data-drupal-selector="edit-author" id="edit-author" open="open">');
     // Only one extra details element should now be open.
     $open_details_elements++;
     $this->assertEqual(count($this->cssSelect('details[open="open"]')), $open_details_elements, 'Exactly one extra open &lt;details&gt; element found.');
+
+    // Edit the same node, save it and verify it's unpublished after unchecking
+    // the 'Published' boolean_checkbox and clicking 'Save'.
+    $this->drupalGet("node/" . $node->id() . "/edit");
+    $edit = array('status[value]' => FALSE);
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->nodeStorage->resetCache(array($node->id()));
+    $node = $this->nodeStorage->load($node->id());
+    $this->assertFalse($node->isPublished(), 'Node is unpublished');
   }
 
   /**
@@ -143,7 +152,7 @@ public function testNodeEditAuthoredBy() {
     $edit = array();
     $edit['title[0][value]'] = $this->randomMachineName(8);
     $edit[$body_key] = $this->randomMachineName(16);
-    $this->drupalPostForm('node/add/page', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
     // Check that the node was authored by the currently logged in user.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
@@ -172,7 +181,7 @@ public function testNodeEditAuthoredBy() {
     $this->drupalLogin($this->adminUser);
 
     // Save the node without making any changes.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
     $this->nodeStorage->resetCache(array($node->id()));
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
@@ -184,7 +193,7 @@ public function testNodeEditAuthoredBy() {
 
     // Check that saving the node without making any changes keeps the proper
     // author ID.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
     $this->nodeStorage->resetCache(array($node->id()));
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
@@ -203,13 +212,13 @@ protected function checkVariousAuthoredByValues(NodeInterface $node, $form_eleme
     $edit = array(
       $form_element_name => 'invalid-name',
     );
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->assertRaw(t('There are no entities matching "%name".', array('%name' => 'invalid-name')));
 
     // Change the authored by field to an empty string, which should assign
     // authorship to the anonymous user (uid 0).
     $edit[$form_element_name] = '';
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->nodeStorage->resetCache(array($node->id()));
     $node = $this->nodeStorage->load($node->id());
     $uid = $node->getOwnerId();
@@ -228,7 +237,7 @@ protected function checkVariousAuthoredByValues(NodeInterface $node, $form_eleme
     // Change the authored by field to another user's name (that is not
     // logged in).
     $edit[$form_element_name] = $this->webUser->getUsername();
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->nodeStorage->resetCache(array($node->id()));
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.');
diff --git a/core/modules/node/src/Tests/NodeFormButtonsTest.php b/core/modules/node/src/Tests/NodeFormButtonsTest.php
deleted file mode 100644
index 9f6732b..0000000
--- a/core/modules/node/src/Tests/NodeFormButtonsTest.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-
-namespace Drupal\node\Tests;
-
-/**
- * Tests all the different buttons on the node form.
- *
- * @group node
- */
-class NodeFormButtonsTest extends NodeTestBase {
-
-  use AssertButtonsTrait;
-
-  /**
-   * A normal logged in user.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $webUser;
-
-  /**
-   * A user with permission to bypass access content.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $adminUser;
-
-  protected function setUp() {
-    parent::setUp();
-
-    // Create a user that has no access to change the state of the node.
-    $this->webUser = $this->drupalCreateUser(array('create article content', 'edit own article content'));
-    // Create a user that has access to change the state of the node.
-    $this->adminUser = $this->drupalCreateUser(array('administer nodes', 'bypass node access'));
-  }
-
-  /**
-   * Tests that the right buttons are displayed for saving nodes.
-   */
-  function testNodeFormButtons() {
-    $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    // Log in as administrative user.
-    $this->drupalLogin($this->adminUser);
-
-    // Verify the buttons on a node add form.
-    $this->drupalGet('node/add/article');
-    $this->assertButtons(array(t('Save and publish'), t('Save as unpublished')));
-
-    // Save the node and assert it's published after clicking
-    // 'Save and publish'.
-    $edit = array('title[0][value]' => $this->randomString());
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
-
-    // Get the node.
-    $node_1 = $node_storage->load(1);
-    $this->assertTrue($node_1->isPublished(), 'Node is published');
-
-    // Verify the buttons on a node edit form.
-    $this->drupalGet('node/' . $node_1->id() . '/edit');
-    $this->assertButtons(array(t('Save and keep published'), t('Save and unpublish')));
-
-    // Save the node and verify it's still published after clicking
-    // 'Save and keep published'.
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
-    $node_storage->resetCache(array(1));
-    $node_1 = $node_storage->load(1);
-    $this->assertTrue($node_1->isPublished(), 'Node is published');
-
-    // Save the node and verify it's unpublished after clicking
-    // 'Save and unpublish'.
-    $this->drupalPostForm('node/' . $node_1->id() . '/edit', $edit, t('Save and unpublish'));
-    $node_storage->resetCache(array(1));
-    $node_1 = $node_storage->load(1);
-    $this->assertFalse($node_1->isPublished(), 'Node is unpublished');
-
-    // Verify the buttons on an unpublished node edit screen.
-    $this->drupalGet('node/' . $node_1->id() . '/edit');
-    $this->assertButtons(array(t('Save and keep unpublished'), t('Save and publish')));
-
-    // Create a node as a normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-
-    // Verify the buttons for a normal user.
-    $this->drupalGet('node/add/article');
-    $this->assertButtons(array(t('Save')), FALSE);
-
-    // Create the node.
-    $edit = array('title[0][value]' => $this->randomString());
-    $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $node_2 = $node_storage->load(2);
-    $this->assertTrue($node_2->isPublished(), 'Node is published');
-
-    // Log in as an administrator and unpublish the node that just
-    // was created by the normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->adminUser);
-    $this->drupalPostForm('node/' . $node_2->id() . '/edit', array(), t('Save and unpublish'));
-    $node_storage->resetCache(array(2));
-    $node_2 = $node_storage->load(2);
-    $this->assertFalse($node_2->isPublished(), 'Node is unpublished');
-
-    // Log in again as the normal user, save the node and verify
-    // it's still unpublished.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-    $this->drupalPostForm('node/' . $node_2->id() . '/edit', array(), t('Save'));
-    $node_storage->resetCache(array(2));
-    $node_2 = $node_storage->load(2);
-    $this->assertFalse($node_2->isPublished(), 'Node is still unpublished');
-    $this->drupalLogout();
-
-    // Set article content type default to unpublished. This will change the
-    // the initial order of buttons and/or status of the node when creating
-    // a node.
-    $fields = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
-    $fields['status']->getConfig('article')
-      ->setDefaultValue(FALSE)
-      ->save();
-
-    // Verify the buttons on a node add form for an administrator.
-    $this->drupalLogin($this->adminUser);
-    $this->drupalGet('node/add/article');
-    $this->assertButtons(array(t('Save as unpublished'), t('Save and publish')));
-
-    // Verify the node is unpublished by default for a normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-    $edit = array('title[0][value]' => $this->randomString());
-    $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $node_3 = $node_storage->load(3);
-    $this->assertFalse($node_3->isPublished(), 'Node is unpublished');
-  }
-
-}
diff --git a/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php b/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php
index a6ffb3b..d5d7974 100644
--- a/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php
+++ b/core/modules/node/src/Tests/NodeRevisionsUiBypassAccessTest.php
@@ -67,7 +67,7 @@ function testDisplayRevisionTab() {
 
     // Uncheck the create new revision checkbox and save the node.
     $edit = array('revision' => FALSE);
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
 
     $this->assertUrl($node->toUrl());
     $this->assertNoLink(t('Revisions'));
@@ -78,7 +78,7 @@ function testDisplayRevisionTab() {
 
     // Submit the form without changing the checkbox.
     $edit = array();
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
 
     $this->assertUrl($node->toUrl());
     $this->assertLink(t('Revisions'));
diff --git a/core/modules/node/src/Tests/NodeRevisionsUiTest.php b/core/modules/node/src/Tests/NodeRevisionsUiTest.php
index cf609b8..6ac7240 100644
--- a/core/modules/node/src/Tests/NodeRevisionsUiTest.php
+++ b/core/modules/node/src/Tests/NodeRevisionsUiTest.php
@@ -55,7 +55,7 @@ function testNodeFormSaveWithoutRevision() {
 
     // Uncheck the create new revision checkbox and save the node.
     $edit = array('revision' => FALSE);
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Load the node again and check the revision is the same as before.
     $node_storage->resetCache(array($node->id()));
@@ -68,7 +68,7 @@ function testNodeFormSaveWithoutRevision() {
 
     // Submit the form without changing the checkbox.
     $edit = array();
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Load the node again and check the revision is different from before.
     $node_storage->resetCache(array($node->id()));
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index 063469d..4d248b7 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -99,7 +99,9 @@ public function testPublishedStatusNoFields() {
       'source' => $default_langcode,
       'target' => $langcode
     ], array('language' => $language));
-    $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), t('Save and unpublish (this translation)'));
+    $edit = $this->getEditValues($values, $langcode);
+    $edit['status[value]'] = FALSE;
+    $this->drupalPostForm($add_url, $edit, t('Save (this translation)'));
 
     $storage->resetCache([$this->entityId]);
     $entity = $storage->load($this->entityId);
@@ -139,18 +141,6 @@ protected function getNewEntityValues($langcode) {
   /**
    * {@inheritdoc}
    */
-  protected function getFormSubmitAction(EntityInterface $entity, $langcode) {
-    if ($entity->getTranslation($langcode)->isPublished()) {
-      return t('Save and keep published') . $this->getFormSubmitSuffix($entity, $langcode);
-    }
-    else {
-      return t('Save and keep unpublished') . $this->getFormSubmitSuffix($entity, $langcode);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   protected function doTestPublishedStatus() {
     $storage = $this->container->get('entity_type.manager')
       ->getStorage($this->entityTypeId);
@@ -158,18 +148,18 @@ protected function doTestPublishedStatus() {
     $entity = $storage->load($this->entityId);
     $languages = $this->container->get('language_manager')->getLanguages();
 
-    $actions = array(
-      t('Save and keep published'),
-      t('Save and unpublish'),
+    $statuses = array(
+      TRUE,
+      FALSE,
     );
 
-    foreach ($actions as $index => $action) {
+    foreach ($statuses as $index => $value) {
       // (Un)publish the node translations and check that the translation
       // statuses are (un)published accordingly.
       foreach ($this->langcodes as $langcode) {
         $options = array('language' => $languages[$langcode]);
         $url = $entity->urlInfo('edit-form', $options);
-        $this->drupalPostForm($url, array(), $action . $this->getFormSubmitSuffix($entity, $langcode), $options);
+        $this->drupalPostForm($url, ['status[value]' => $value], t('Save') . $this->getFormSubmitSuffix($entity, $langcode), $options);
       }
       $storage->resetCache([$this->entityId]);
       $entity = $storage->load($this->entityId);
diff --git a/core/modules/node/src/Tests/Update/NodeUpdateTest.php b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
index b8b30be..0111606 100644
--- a/core/modules/node/src/Tests/Update/NodeUpdateTest.php
+++ b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Tests\Update;
 
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\system\Tests\Update\UpdatePathTestBase;
 
 /**
@@ -38,4 +39,29 @@ public function testPublishedEntityKey() {
     $this->assertEqual('status', $entity_type->getKey('published'));
   }
 
+  /**
+   * Tests that the node entity form has the status checkbox.
+   *
+   * @see node_update_8302()
+   */
+  public function testStatusCheckbox() {
+    // Run updates.
+    $this->runUpdates();
+
+    $query = \Drupal::entityQuery('entity_form_display')
+      ->condition('targetEntityType', 'node');
+    $ids = $query->execute();
+    $form_displays = EntityFormDisplay::loadMultiple($ids);
+
+    /**
+     * @var string $id
+     * @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display
+     */
+    foreach ($form_displays as $id => $form_display) {
+      $component = $form_display->getComponent('status');
+      $this->assertEqual('boolean_checkbox', $component['type']);
+      $this->assertEqual(['display_label' => TRUE], $component['settings']);
+    }
+  }
+
 }
diff --git a/core/modules/options/src/Tests/OptionsFieldUITest.php b/core/modules/options/src/Tests/OptionsFieldUITest.php
index ee6cf2e..6538876 100644
--- a/core/modules/options/src/Tests/OptionsFieldUITest.php
+++ b/core/modules/options/src/Tests/OptionsFieldUITest.php
@@ -328,7 +328,7 @@ function testNodeDisplay() {
     $edit = array(
       $this->fieldName => '1',
     );
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Check the node page and see if the values are correct.
     $file_formatters = array('list_default', 'list_key');
diff --git a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
index 9ca87d6..aed68c2 100644
--- a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
+++ b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
@@ -47,7 +47,7 @@ protected function setUp() {
     // also needs the word "pizza" so we can use it as the search keyword.
     $body_key = 'body[0][value]';
     $edit[$body_key] = \Drupal::l($node->label(), $node->urlInfo()) . ' pizza sandwich';
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex();
     search_update_totals();
diff --git a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
index f756300..3fcbe77 100644
--- a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
@@ -206,7 +206,7 @@ function testBreadCrumbs() {
     $edit = array(
       'menu[menu_parent]' => $link->getMenuName() . ':' . $link->getPluginId(),
     );
-    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save'));
     $expected = array(
       "node" => $link->getTitle(),
     );
@@ -227,7 +227,7 @@ function testBreadCrumbs() {
     $edit = array(
       'field_tags[target_id]' => implode(',', array_keys($tags)),
     );
-    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save'));
 
     // Put both terms into a hierarchy Drupal » Breadcrumbs. Required for both
     // the menu links and the terms itself, since taxonomy_term_page() resets
diff --git a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
index eb95fce..679443f 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
@@ -117,7 +117,7 @@ public function testUpdatedSite() {
     $this->assertText('Test Article - New title');
     $this->assertText('Test 1');
     $this->assertRaw('0.01');
-    $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)');
+    $this->drupalPostForm('node/8/edit', [], 'Save (this translation)');
     $this->assertResponse(200);
     $this->drupalGet('node/8/edit', ['language' => $spanish]);
     $this->assertText('Test title Spanish');
diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
index 6edbfe3..dd8d6f2 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
@@ -117,7 +117,7 @@ public function testUpdatedSite() {
     $this->assertText('Test Article - New title');
     $this->assertText('Test 1');
     $this->assertRaw('0.01');
-    $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)');
+    $this->drupalPostForm('node/8/edit', [], 'Save (this translation)');
     $this->assertResponse(200);
     $this->drupalGet('node/8/edit', ['language' => $spanish]);
     $this->assertText('Test title Spanish');
diff --git a/core/modules/taxonomy/src/Tests/LegacyTest.php b/core/modules/taxonomy/src/Tests/LegacyTest.php
index b842226..777cd50 100644
--- a/core/modules/taxonomy/src/Tests/LegacyTest.php
+++ b/core/modules/taxonomy/src/Tests/LegacyTest.php
@@ -60,7 +60,7 @@ function testTaxonomyLegacyNode() {
     $edit['created[0][value][time]'] = $date->format('H:i:s');
     $edit['body[0][value]'] = $this->randomMachineName();
     $edit['field_tags[target_id]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
     // Checks that the node has been saved.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.');
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
index c94e36e..9082f2d 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
@@ -66,6 +66,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
index 0b7ffd1..189aef5 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
@@ -40,6 +40,12 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
